uint32 group_entries = 0;
uint32 i;
TALLOC_CTX *mem_ctx = info->mem_ctx;
+ BOOL ret;
DEBUG(10,("load_group_domain_entries\n"));
become_root();
-
- if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
+ ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
+ unbecome_root();
+
+ if ( !ret ) {
DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
return NT_STATUS_NO_MEMORY;
}
- unbecome_root();
info->disp_info.num_group_account=group_entries;
DOM_SID sid;
GROUP_MAP map;
uint32 acc_granted;
+ BOOL ret;
r_u->status = NT_STATUS_OK;
!sid_check_is_in_builtin(&sid))
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- if (!pdb_getgrsid(&map, sid))
+ become_root();
+ ret = pdb_getgrsid(&map, sid);
+ unbecome_root();
+
+ if ( !ret )
return NT_STATUS_NO_SUCH_ALIAS;
switch (q_u->switch_level) {
DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
- become_root(); /* local_lookup_name can require root privs */
-
for (i = 0; i < num_rids; i++) {
fstring name;
DOM_SID sid;
if (sid_equal(&sid, &pol_sid)) {
rid[i]=local_rid;
- type[i]=local_type;
+
+ /* Windows does not return WKN_GRP here, even
+ * on lookups in builtin */
+ type[i] = (local_type == SID_NAME_WKN_GRP) ?
+ SID_NAME_ALIAS : local_type;
+
r_u->status = NT_STATUS_OK;
}
}
}
- unbecome_root();
-
init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
return nt_status;
}
+ if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
+ /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
+ this parameter is not an account type */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
/* find the account: tell the caller if it exists.
lkclXXXX i have *no* idea if this is a problem or not
or even if you are supposed to construct a different
acct_ctrl = pdb_get_acct_ctrl(pwd);
- if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
+ if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
pdb_free_sam(&pwd);
return False;
}
DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
} else {
/* update the UNIX password */
- if (lp_unix_password_sync() )
- if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
+ if (lp_unix_password_sync() ) {
+ struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
+ if (!passwd) {
+ DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
+ }
+
+ if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
pdb_free_sam(&pwd);
return False;
}
+ }
}
ZERO_STRUCT(plaintext_buf);
ZERO_STRUCT(plaintext_buf);
- if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
+ if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
pdb_free_sam(&pwd);
return False;
}
} else {
/* update the UNIX password */
if (lp_unix_password_sync()) {
- if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
+ struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
+ if (!passwd) {
+ DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
+ }
+
+ if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
pdb_free_sam(&pwd);
return False;
}
break;
case 24:
- if (p->session_key.length != 16) {
- /* we may have no session key at all,
- and we don't know how to do the SamOEMhash
- for length != 16 */
+ if (!p->session_key.length) {
return NT_STATUS_NO_USER_SESSION_KEY;
}
- SamOEMhash(ctr->info.id24->pass, p->session_key.data, 516);
+ SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
dump_data(100, (char *)ctr->info.id24->pass, 516);
* info level and W2K SP2 drops down to level 23... JRA.
*/
- if (p->session_key.length != 16) {
+ if (!p->session_key.length) {
return NT_STATUS_NO_USER_SESSION_KEY;
}
- SamOEMhash(ctr->info.id25->pass, p->session_key.data, 532);
+ SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
dump_data(100, (char *)ctr->info.id25->pass, 532);
return NT_STATUS_INVALID_INFO_CLASS;
case 23:
- if (p->session_key.length != 16) {
+ if (!p->session_key.length) {
return NT_STATUS_NO_USER_SESSION_KEY;
}
- SamOEMhash(ctr->info.id23->pass, p->session_key.data, 516);
+ SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
dump_data(100, (char *)ctr->info.id23->pass, 516);
int i;
GROUP_MAP map;
- int num_uids = 0;
+ int num_sids = 0;
DOM_SID2 *sid;
- uid_t *uid=NULL;
+ DOM_SID *sids=NULL;
DOM_SID alias_sid;
DOM_SID als_sid;
uint32 alias_rid;
fstring alias_sid_str;
- DOM_SID temp_sid;
- SAM_ACCOUNT *sam_user = NULL;
- BOOL check;
uint32 acc_granted;
/* find the policy handle. open a policy on it. */
if (sid_equal(&alias_sid, &global_sid_Builtin)) {
DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
- if(!get_builtin_group_from_sid(als_sid, &map))
+ if(!get_builtin_group_from_sid(&als_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
} else {
if (sid_equal(&alias_sid, get_global_sam_sid())) {
DEBUG(10, ("lookup on Server SID\n"));
- if(!get_local_group_from_sid(als_sid, &map))
+ if(!get_local_group_from_sid(&als_sid, &map)) {
+ fstring alias_sid_string;
+ DEBUG(10, ("Alias %s not found\n", sid_to_string(alias_sid_string, &als_sid)));
return NT_STATUS_NO_SUCH_ALIAS;
+ }
}
}
- if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
+ if (!get_sid_list_of_group(map.gid, &sids, &num_sids)) {
+ fstring alias_sid_string;
+ DEBUG(10, ("Alias %s found, but member list unavailable\n", sid_to_string(alias_sid_string, &als_sid)));
return NT_STATUS_NO_SUCH_ALIAS;
+ }
DEBUG(10, ("sid is %s\n", alias_sid_str));
- sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
- if (num_uids!=0 && sid == NULL)
+ sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
+ if (num_sids!=0 && sid == NULL) {
+ SAFE_FREE(sids);
return NT_STATUS_NO_MEMORY;
+ }
- for (i = 0; i < num_uids; i++) {
- struct passwd *pass;
- uint32 rid;
-
- sid_copy(&temp_sid, get_global_sam_sid());
-
- pass = getpwuid_alloc(uid[i]);
- if (!pass) continue;
-
- if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
- passwd_free(&pass);
- continue;
- }
-
- become_root();
- check = pdb_getsampwnam(sam_user, pass->pw_name);
- unbecome_root();
-
- if (check != True) {
- pdb_free_sam(&sam_user);
- passwd_free(&pass);
- continue;
- }
-
- rid = pdb_get_user_rid(sam_user);
- if (rid == 0) {
- pdb_free_sam(&sam_user);
- passwd_free(&pass);
- continue;
- }
-
- pdb_free_sam(&sam_user);
- passwd_free(&pass);
-
- sid_append_rid(&temp_sid, rid);
-
- init_dom_sid2(&sid[i], &temp_sid);
+ for (i = 0; i < num_sids; i++) {
+ init_dom_sid2(&sid[i], &sids[i]);
}
DEBUG(10, ("sid is %s\n", alias_sid_str));
- init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
+ init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
+
+ SAFE_FREE(sids);
return NT_STATUS_OK;
}
NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
{
- int num_uids = 0;
+ int num_sids = 0;
+ int final_num_sids = 0;
int i;
DOM_SID group_sid;
- uint32 group_rid;
fstring group_sid_str;
- uid_t *uid=NULL;
+ DOM_SID *sids=NULL;
GROUP_MAP map;
uint32 *rid=NULL;
uint32 *attr=NULL;
- SAM_ACCOUNT *sam_user = NULL;
- BOOL check;
uint32 acc_granted;
/* find the policy handle. open a policy on it. */
return r_u->status;
}
- /* todo: change to use sid_compare_front */
-
- sid_split_rid(&group_sid, &group_rid);
sid_to_string(group_sid_str, &group_sid);
DEBUG(10, ("sid is %s\n", group_sid_str));
- /* can we get a query for an SID outside our domain ? */
- if (!sid_equal(&group_sid, get_global_sam_sid()))
+ if (!sid_check_is_in_our_domain(&group_sid)) {
+ DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
return NT_STATUS_NO_SUCH_GROUP;
+ }
- sid_append_rid(&group_sid, group_rid);
DEBUG(10, ("lookup on Domain SID\n"));
if(!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
- if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
+ if(!get_sid_list_of_group(map.gid, &sids, &num_sids))
return NT_STATUS_NO_SUCH_GROUP;
- rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
- attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
+ rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids);
+ attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids);
- if (num_uids!=0 && (rid==NULL || attr==NULL))
+ if (num_sids!=0 && (rid==NULL || attr==NULL))
return NT_STATUS_NO_MEMORY;
- for (i=0; i<num_uids; i++) {
- struct passwd *pass;
+ for (i=0; i<num_sids; i++) {
uint32 urid;
-
- pass = getpwuid_alloc(uid[i]);
- if (!pass) continue;
-
- if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
- passwd_free(&pass);
- continue;
- }
-
- become_root();
- check = pdb_getsampwnam(sam_user, pass->pw_name);
- unbecome_root();
-
- if (check != True) {
- pdb_free_sam(&sam_user);
- passwd_free(&pass);
- continue;
- }
-
- urid = pdb_get_user_rid(sam_user);
- if (urid == 0) {
- pdb_free_sam(&sam_user);
- passwd_free(&pass);
- continue;
+
+ if (sid_peek_check_rid(get_global_sam_sid(), &sids[i], &urid)) {
+ rid[final_num_sids] = urid;
+ attr[final_num_sids] = SID_NAME_USER;
+ final_num_sids++;
+ } else {
+ fstring user_sid_str, domain_sid_str;
+ DEBUG(1, ("_samr_query_groupmem: SID %s in group %s is not in our domain %s\n",
+ sid_to_string(user_sid_str, &sids[i]),
+ sid_to_string(group_sid_str, &group_sid),
+ sid_to_string(domain_sid_str, get_global_sam_sid())));
}
-
- pdb_free_sam(&sam_user);
- passwd_free(&pass);
-
- rid[i] = urid;
- attr[i] = SID_NAME_USER;
}
- init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
+ init_samr_r_query_groupmem(r_u, final_num_sids, rid, attr, NT_STATUS_OK);
return NT_STATUS_OK;
}
if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
DEBUG(10, ("adding member on Server SID\n"));
- if(!get_local_group_from_sid(alias_sid, &map))
+ if(!get_local_group_from_sid(&alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
} else {
if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
DEBUG(10, ("adding member on BUILTIN SID\n"));
- if( !get_local_group_from_sid(alias_sid, &map))
+ if( !get_builtin_group_from_sid(&alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
} else
return NT_STATUS_NO_SUCH_ALIAS;
}
- if( !get_local_group_from_sid(alias_sid, &map))
+ if( !get_local_group_from_sid(&alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
if ((grp=getgrgid(map.gid)) == NULL)
if ( (grp=getgrgid(gid)) == NULL)
return NT_STATUS_NO_SUCH_GROUP;
+ /* delete mapping first */
+ if(!pdb_delete_group_mapping_entry(group_sid))
+ return NT_STATUS_ACCESS_DENIED;
+
/* we can delete the UNIX group */
smb_delete_group(grp->gr_name);
if ( (grp=getgrgid(gid)) != NULL)
return NT_STATUS_ACCESS_DENIED;
- if(!pdb_delete_group_mapping_entry(group_sid))
- return NT_STATUS_ACCESS_DENIED;
if (!close_policy_hnd(p, &q_u->group_pol))
return NT_STATUS_OBJECT_NAME_INVALID;
DEBUG(10, ("lookup on Local SID\n"));
- if(!get_local_group_from_sid(alias_sid, &map))
+ if(!get_local_group_from_sid(&alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
gid=map.gid;
{
DOM_SID group_sid;
GROUP_MAP map;
- uid_t *uid=NULL;
- int num_uids=0;
+ DOM_SID *sids=NULL;
+ int num_sids=0;
GROUP_INFO_CTR *ctr;
uint32 acc_granted;
BOOL ret;
switch (q_u->switch_level) {
case 1:
ctr->switch_value1 = 1;
- if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
+ if(!get_sid_list_of_group(map.gid, &sids, &num_sids))
return NT_STATUS_NO_SUCH_GROUP;
- init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
- SAFE_FREE(uid);
+ init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_sids);
+ SAFE_FREE(sids);
break;
case 3:
ctr->switch_value1 = 3;
return r_u->status;
}
- if (!get_local_group_from_sid(group_sid, &map))
+ if (!get_local_group_from_sid(&group_sid, &map) &&
+ !get_builtin_group_from_sid(&group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
ctr=&q_u->ctr;
}
/*********************************************************************
- _samr_remove_user_foreign_domain
+ _samr_remove_sid_foreign_domain
*********************************************************************/
-NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p,
- SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u,
- SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
+NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
+ SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
+ SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
{
- DOM_SID user_sid, dom_sid;
+ DOM_SID delete_sid, alias_sid;
SAM_ACCOUNT *sam_pass=NULL;
uint32 acc_granted;
+ GROUP_MAP map;
+ BOOL is_user = False;
+ NTSTATUS result;
+ enum SID_NAME_USE type = SID_NAME_UNKNOWN;
- sid_copy( &user_sid, &q_u->sid.sid );
+ sid_copy( &delete_sid, &q_u->sid.sid );
- DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
- sid_string_static(&user_sid)));
+ DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
+ sid_string_static(&delete_sid)));
/* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
+ if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
return NT_STATUS_INVALID_HANDLE;
+
+ result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
+ "_samr_remove_sid_foreign_domain");
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted,
- STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain")))
- {
- return r_u->status;
- }
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
+ sid_string_static(&alias_sid)));
- if ( !sid_check_is_in_our_domain(&user_sid) ) {
- DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
- return NT_STATUS_NO_SUCH_USER;
+ /* make sure we can handle this */
+
+ if ( sid_check_is_domain(&alias_sid) )
+ type = SID_NAME_DOM_GRP;
+ else if ( sid_check_is_builtin(&alias_sid) )
+ type = SID_NAME_ALIAS;
+
+ if ( type == SID_NAME_UNKNOWN ) {
+ DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
+ return NT_STATUS_OK;
}
/* check if the user exists before trying to delete */
pdb_init_sam(&sam_pass);
- if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
+ if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
+ is_user = True;
+ } else {
+ /* maybe it is a group */
+ if( !pdb_getgrsid(&map, delete_sid) ) {
+ DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
+ sid_string_static(&delete_sid)));
+ result = NT_STATUS_INVALID_SID;
+ goto done;
+ }
+ }
- DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n",
- sid_string_static(&user_sid)));
-
- pdb_free_sam(&sam_pass);
+ /* we can only delete a user from a group since we don't have
+ nested groups anyways. So in the latter case, just say OK */
+
+ if ( is_user ) {
+ GROUP_MAP *mappings = NULL;
+ int num_groups, i;
+ struct group *grp2;
- return NT_STATUS_NO_SUCH_USER;
- }
+ if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
+
+ /* interate over the groups */
+ for ( i=0; i<num_groups; i++ ) {
- /*
- * delete the unix side
- *
- * note: we don't check if the delete really happened
- * as the script is not necessary present
- * and maybe the sysadmin doesn't want to delete the unix side
- */
-
- smb_delete_user(pdb_get_username(sam_pass));
+ grp2 = getgrgid(mappings[i].gid);
- /* and delete the samba side */
-
- if ( !pdb_delete_sam_account(sam_pass) ) {
-
- DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
- pdb_free_sam(&sam_pass);
-
- return NT_STATUS_CANNOT_DELETE;
+ if ( !grp2 ) {
+ DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
+ continue;
+ }
+
+ if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
+ continue;
+
+ smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
+
+ if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
+ /* should we fail here ? */
+ DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
+ pdb_get_username(sam_pass), grp2->gr_name ));
+ continue;
+ }
+
+ DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
+ pdb_get_username(sam_pass), grp2->gr_name ));
+ }
+
+ SAFE_FREE(mappings);
+ }
}
+ result = NT_STATUS_OK;
+done:
+
pdb_free_sam(&sam_pass);
- return NT_STATUS_OK;
+ return result;
}
/*******************************************************************
case 0x07:
break;
case 0x0c:
- u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
- u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
+ u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
+ u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);