X-Git-Url: http://git.samba.org/samba.git/?p=ira%2Fwip.git;a=blobdiff_plain;f=source3%2Frpc_server%2Fsrv_samr_nt.c;h=52864fcaa092ce5f1bd8d9bfd1ef9a0360846705;hp=17e111d4eac88391980b46feebbc988f1e66e6ac;hb=59192bf03f3781fe6a21be66a7374ea72cac71f4;hpb=705f36b804093f656498f7963768a418672cd422 diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 17e111d4eac..52864fcaa09 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -185,7 +185,8 @@ static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token, by privileges (mostly having to do with creating/modifying/deleting users and groups) */ - if ( rights && user_has_any_privilege( token, rights ) ) { + if (rights && !se_priv_equal(rights, &se_priv_none) && + user_has_any_privilege(token, rights)) { saved_mask = (des_access & rights_mask); des_access &= ~saved_mask; @@ -552,11 +553,15 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p, make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 ); se_map_generic( &des_access, &dom_generic_mapping ); + /* + * Users with SeMachineAccount or SeAddUser get additional + * SAMR_DOMAIN_ACCESS_CREATE_USER access, but no more. + */ se_priv_copy( &se_rights, &se_machine_account ); se_priv_add( &se_rights, &se_add_users ); status = access_check_samr_object( psd, p->server_info->ptok, - &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access, + &se_rights, SAMR_DOMAIN_ACCESS_CREATE_USER, des_access, &acc_granted, "_samr_OpenDomain" ); if ( !NT_STATUS_IS_OK(status) ) @@ -1460,8 +1465,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, /* THe following done as ROOT. Don't return without unbecome_root(). */ switch (r->in.level) { - case 0x1: - case 0x4: + case 1: + case 4: if (dinfo->disp_info->users == NULL) { dinfo->disp_info->users = pdb_search_users( dinfo->disp_info, ACB_NORMAL); @@ -1480,7 +1485,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, enum_context, max_entries, &entries); break; - case 0x2: + case 2: if (dinfo->disp_info->machines == NULL) { dinfo->disp_info->machines = pdb_search_users( dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST); @@ -1499,8 +1504,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, enum_context, max_entries, &entries); break; - case 0x3: - case 0x5: + case 3: + case 5: if (dinfo->disp_info->groups == NULL) { dinfo->disp_info->groups = pdb_search_groups( dinfo->disp_info); @@ -1529,27 +1534,27 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, /* Now create reply structure */ switch (r->in.level) { - case 0x1: + case 1: disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1, num_account, enum_context, entries); break; - case 0x2: + case 2: disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2, num_account, enum_context, entries); break; - case 0x3: + case 3: disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3, num_account, enum_context, entries); break; - case 0x4: + case 4: disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4, num_account, enum_context, entries); break; - case 0x5: + case 5: disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5, num_account, enum_context, entries); @@ -2207,6 +2212,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, SEC_DESC *psd = NULL; uint32 acc_granted; uint32 des_access = r->in.access_mask; + uint32_t extra_access = 0; size_t sd_size; bool ret; NTSTATUS nt_status; @@ -2236,8 +2242,70 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); se_map_generic(&des_access, &usr_generic_mapping); - se_priv_copy( &se_rights, &se_machine_account ); - se_priv_add( &se_rights, &se_add_users ); + /* + * Get the sampass first as we need to check privilages + * based on what kind of user object this is. + * But don't reveal info too early if it didn't exist. + */ + + become_root(); + ret=pdb_getsampwsid(sampass, &sid); + unbecome_root(); + + se_priv_copy(&se_rights, &se_priv_none); + + /* + * We do the override access checks on *open*, not at + * SetUserInfo time. + */ + if (ret) { + uint32_t acb_info = pdb_get_acct_ctrl(sampass); + + if ((acb_info & ACB_WSTRUST) && + user_has_any_privilege(p->server_info->ptok, + &se_machine_account)) { + /* + * SeMachineAccount is needed to add + * GENERIC_RIGHTS_USER_WRITE to a machine + * account. + */ + se_priv_add(&se_rights, &se_machine_account); + DEBUG(10,("_samr_OpenUser: adding machine account " + "rights to handle for user %s\n", + pdb_get_username(sampass) )); + } + if ((acb_info & ACB_NORMAL) && + user_has_any_privilege(p->server_info->ptok, + &se_add_users)) { + /* + * SeAddUsers is needed to add + * GENERIC_RIGHTS_USER_WRITE to a normal + * account. + */ + se_priv_add(&se_rights, &se_add_users); + DEBUG(10,("_samr_OpenUser: adding add user " + "rights to handle for user %s\n", + pdb_get_username(sampass) )); + } + /* + * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is + * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not + * what Windows does but is a hack for people who haven't + * set up privilages 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)) { + des_access &= ~GENERIC_RIGHTS_USER_WRITE; + extra_access = GENERIC_RIGHTS_USER_WRITE; + DEBUG(4,("_samr_OpenUser: Allowing " + "GENERIC_RIGHTS_USER_WRITE for " + "rid admins\n")); + } + } + } + + TALLOC_FREE(sampass); nt_status = access_check_samr_object(psd, p->server_info->ptok, &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, @@ -2246,16 +2314,13 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, if ( !NT_STATUS_IS_OK(nt_status) ) return nt_status; - become_root(); - ret=pdb_getsampwsid(sampass, &sid); - unbecome_root(); - /* check that the SID exists in our domain. */ if (ret == False) { return NT_STATUS_NO_SUCH_USER; } - TALLOC_FREE(sampass); + /* If we did the rid admins hack above, allow access. */ + acc_granted |= extra_access; uinfo = policy_handle_create(p, r->out.user_handle, acc_granted, struct samr_user_info, &nt_status); @@ -2665,7 +2730,7 @@ static NTSTATUS get_user_info_18(pipes_struct *p, if (ret == False) { DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid))); TALLOC_FREE(smbpass); - return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED; + return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED; } DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) )); @@ -2959,10 +3024,15 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p, break; } - TALLOC_FREE(pwd); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } *r->out.info = user_info; + done: + TALLOC_FREE(pwd); + DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__)); return status; @@ -3131,11 +3201,41 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, time_t seq_num; uint32 server_role; + uint32_t acc_required; DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__)); + switch (r->in.level) { + case 1: /* DomainPasswordInformation */ + case 12: /* DomainLockoutInformation */ + /* DOMAIN_READ_PASSWORD_PARAMETERS */ + acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1; + break; + case 11: /* DomainGeneralInformation2 */ + /* DOMAIN_READ_PASSWORD_PARAMETERS | + * DOMAIN_READ_OTHER_PARAMETERS */ + acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | + SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2; + break; + case 2: /* DomainGeneralInformation */ + case 3: /* DomainLogoffInformation */ + case 4: /* DomainOemInformation */ + case 5: /* DomainReplicationInformation */ + case 6: /* DomainReplicationInformation */ + case 7: /* DomainServerRoleInformation */ + case 8: /* DomainModifiedInformation */ + case 9: /* DomainStateInformation */ + case 10: /* DomainUasInformation */ + case 13: /* DomainModifiedInformation2 */ + /* DOMAIN_READ_OTHER_PARAMETERS */ + acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2; + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + dinfo = policy_handle_find(p, r->in.domain_handle, - SAMR_ACCESS_LOOKUP_DOMAIN, NULL, + acc_required, NULL, struct samr_domain_info, &status); if (!NT_STATUS_IS_OK(status)) { return status; @@ -3147,7 +3247,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, } switch (r->in.level) { - case 0x01: + case 1: become_root(); @@ -3181,7 +3281,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, } break; - case 0x02: + case 2: become_root(); @@ -3218,7 +3318,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, dom_info->general.unknown3 = 1; break; - case 0x03: + case 3: become_root(); @@ -3237,26 +3337,26 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout); break; - case 0x04: + case 4: dom_info->oem.oem_information.string = lp_serverstring(); break; - case 0x05: + case 5: dom_info->info5.domain_name.string = get_global_sam_name(); break; - case 0x06: + case 6: /* NT returns its own name when a PDC. win2k and later * only the name of the PDC if itself is a BDC (samba4 * idl) */ dom_info->info6.primary.string = global_myname(); break; - case 0x07: + case 7: server_role = ROLE_DOMAIN_PDC; if (lp_server_role() == ROLE_DOMAIN_BDC) server_role = ROLE_DOMAIN_BDC; dom_info->info7.role = server_role; break; - case 0x08: + case 8: become_root(); @@ -3274,12 +3374,12 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, dom_info->info8.domain_create_time = 0; break; - case 0x09: + case 9: dom_info->info9.domain_server_state = DOMAIN_SERVER_ENABLED; break; - case 0x0b: + case 11: /* AS ROOT !!! */ @@ -3334,7 +3434,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, u_reset_time); break; - case 0x0c: + case 12: become_root(); @@ -3363,7 +3463,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, u_reset_time); break; - case 0x0d: + case 13: become_root(); @@ -3483,47 +3583,44 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, /* determine which user right we need to check based on the acb_info */ - if ( acb_info & ACB_WSTRUST ) - { - se_priv_copy( &se_rights, &se_machine_account ); + if (geteuid() == sec_initial_uid()) { + se_priv_copy(&se_rights, &se_priv_none); + can_add_account = true; + } else if (acb_info & ACB_WSTRUST) { + se_priv_copy(&se_rights, &se_machine_account); can_add_account = user_has_privileges( p->server_info->ptok, &se_rights ); - } - /* usrmgr.exe (and net rpc trustdom grant) creates a normal user - account for domain trusts and changes the ACB flags later */ - else if ( acb_info & ACB_NORMAL && - (account[strlen(account)-1] != '$') ) - { - se_priv_copy( &se_rights, &se_add_users ); + } else if (acb_info & ACB_NORMAL && + (account[strlen(account)-1] != '$')) { + /* usrmgr.exe (and net rpc trustdom grant) creates a normal user + account for domain trusts and changes the ACB flags later */ + se_priv_copy(&se_rights, &se_add_users); can_add_account = user_has_privileges( p->server_info->ptok, &se_rights ); - } - else /* implicit assumption of a BDC or domain trust account here + } else if (lp_enable_privileges()) { + /* implicit assumption of a BDC or domain trust account here * (we already check the flags earlier) */ - { - if ( lp_enable_privileges() ) { - /* only Domain Admins can add a BDC or domain trust */ - se_priv_copy( &se_rights, &se_priv_none ); - can_add_account = nt_token_check_domain_rid( - p->server_info->ptok, - DOMAIN_GROUP_RID_ADMINS ); - } + /* only Domain Admins can add a BDC or domain trust */ + se_priv_copy(&se_rights, &se_priv_none); + can_add_account = nt_token_check_domain_rid( + p->server_info->ptok, + DOMAIN_GROUP_RID_ADMINS ); } DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n", uidtoname(p->server_info->utok.uid), can_add_account ? "True":"False" )); - /********** BEGIN Admin BLOCK **********/ + if (!can_add_account) { + return NT_STATUS_ACCESS_DENIED; + } - if ( can_add_account ) - become_root(); + /********** BEGIN Admin BLOCK **********/ + become_root(); nt_status = pdb_create_user(p->mem_ctx, account, acb_info, r->out.rid); - - if ( can_add_account ) - unbecome_root(); + unbecome_root(); /********** END Admin BLOCK **********/ @@ -3542,6 +3639,13 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, &sid, SAMR_USR_RIGHTS_WRITE_PW); se_map_generic(&des_access, &usr_generic_mapping); + /* + * JRA - TESTME. We just created this user so we + * had rights to create them. Do we need to check + * any further access on this object ? Can't we + * just assume we have all the rights we need ? + */ + nt_status = access_check_samr_object(psd, p->server_info->ptok, &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, &acc_granted, "_samr_CreateUser2"); @@ -3889,10 +3993,9 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, se_priv_copy( &se_rights, &se_add_users ); - status = access_check_samr_object(psd, p->server_info->ptok, - &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access, - &acc_granted, "_samr_OpenAlias"); + &se_rights, SAMR_ALIAS_ACCESS_ADD_MEMBER, + des_access, &acc_granted, "_samr_OpenAlias"); if ( !NT_STATUS_IS_OK(status) ) return status; @@ -4660,8 +4763,6 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, uint16_t switch_value = r->in.level; uint32_t acc_required; bool ret; - bool has_enough_rights = False; - uint32_t acb_info; DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__)); @@ -4673,6 +4774,9 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, 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: @@ -4713,32 +4817,9 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, return NT_STATUS_NO_SUCH_USER; } - /* deal with machine password changes differently from userinfo changes */ - /* check to see if we have the sufficient rights */ - - acb_info = pdb_get_acct_ctrl(pwd); - if (acb_info & ACB_WSTRUST) - has_enough_rights = user_has_privileges(p->server_info->ptok, - &se_machine_account); - else if (acb_info & ACB_NORMAL) - has_enough_rights = user_has_privileges(p->server_info->ptok, - &se_add_users); - else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) { - if (lp_enable_privileges()) { - has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok, - DOMAIN_GROUP_RID_ADMINS); - } - } - - DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n", - uidtoname(p->server_info->utok.uid), - has_enough_rights ? "" : " not")); + /* ================ BEGIN Privilege BLOCK ================ */ - /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */ - - if (has_enough_rights) { - become_root(); - } + become_root(); /* ok! user info levels (lots: see MSDEV help), off we go... */ @@ -4885,11 +4966,9 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, TALLOC_FREE(pwd); - if (has_enough_rights) { - unbecome_root(); - } + unbecome_root(); - /* ================ END SeMachineAccountPrivilege BLOCK ================ */ + /* ================ END Privilege BLOCK ================ */ if (NT_STATUS_IS_OK(status)) { force_flush_samr_cache(&uinfo->sid); @@ -5105,8 +5184,6 @@ NTSTATUS _samr_AddAliasMember(pipes_struct *p, struct samr_AddAliasMember *r) { struct samr_alias_info *ainfo; - SE_PRIV se_rights; - bool can_add_accounts; NTSTATUS status; ainfo = policy_handle_find(p, r->in.alias_handle, @@ -5118,18 +5195,11 @@ NTSTATUS _samr_AddAliasMember(pipes_struct *p, DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid))); - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); status = pdb_add_aliasmem(&ainfo->sid, r->in.sid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5148,8 +5218,6 @@ NTSTATUS _samr_DeleteAliasMember(pipes_struct *p, struct samr_DeleteAliasMember *r) { struct samr_alias_info *ainfo; - SE_PRIV se_rights; - bool can_add_accounts; NTSTATUS status; ainfo = policy_handle_find(p, r->in.alias_handle, @@ -5162,18 +5230,11 @@ NTSTATUS _samr_DeleteAliasMember(pipes_struct *p, DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", sid_string_dbg(&ainfo->sid))); - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); status = pdb_del_aliasmem(&ainfo->sid, r->in.sid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5194,8 +5255,6 @@ NTSTATUS _samr_AddGroupMember(pipes_struct *p, struct samr_group_info *ginfo; NTSTATUS status; uint32 group_rid; - SE_PRIV se_rights; - bool can_add_accounts; ginfo = policy_handle_find(p, r->in.group_handle, SAMR_GROUP_ACCESS_ADD_MEMBER, NULL, @@ -5211,18 +5270,11 @@ NTSTATUS _samr_AddGroupMember(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; } - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5242,8 +5294,6 @@ NTSTATUS _samr_DeleteGroupMember(pipes_struct *p, struct samr_group_info *ginfo; NTSTATUS status; uint32 group_rid; - SE_PRIV se_rights; - bool can_add_accounts; /* * delete the group member named r->in.rid @@ -5263,18 +5313,11 @@ NTSTATUS _samr_DeleteGroupMember(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; } - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5293,8 +5336,8 @@ NTSTATUS _samr_DeleteUser(pipes_struct *p, struct samr_user_info *uinfo; NTSTATUS status; struct samu *sam_pass=NULL; - bool can_add_accounts; - uint32 acb_info; + bool can_del_accounts = false; + uint32 acb_info = 0; bool ret; DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__)); @@ -5318,31 +5361,36 @@ NTSTATUS _samr_DeleteUser(pipes_struct *p, ret = pdb_getsampwsid(sam_pass, &uinfo->sid); unbecome_root(); - if( !ret ) { - DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n", - sid_string_dbg(&uinfo->sid))); - TALLOC_FREE(sam_pass); - return NT_STATUS_NO_SUCH_USER; + if (ret) { + acb_info = pdb_get_acct_ctrl(sam_pass); } - acb_info = pdb_get_acct_ctrl(sam_pass); - /* For machine accounts it's the SeMachineAccountPrivilege that counts. */ - if ( acb_info & ACB_WSTRUST ) { - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account ); + if (geteuid() == sec_initial_uid()) { + can_del_accounts = true; + } else if (acb_info & ACB_WSTRUST) { + can_del_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account ); } else { - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users ); + can_del_accounts = user_has_privileges( p->server_info->ptok, &se_add_users ); } - /******** BEGIN SeAddUsers BLOCK *********/ + if (!can_del_accounts) { + TALLOC_FREE(sam_pass); + return NT_STATUS_ACCESS_DENIED; + } - if ( can_add_accounts ) - become_root(); + if(!ret) { + DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n", + sid_string_dbg(&uinfo->sid))); + TALLOC_FREE(sam_pass); + return NT_STATUS_NO_SUCH_USER; + } - status = pdb_delete_user(p->mem_ctx, sam_pass); + /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - unbecome_root(); + become_root(); + status = pdb_delete_user(p->mem_ctx, sam_pass); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5377,8 +5425,6 @@ NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p, struct samr_group_info *ginfo; NTSTATUS status; uint32 group_rid; - SE_PRIV se_rights; - bool can_add_accounts; DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__)); @@ -5396,18 +5442,11 @@ NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p, return NT_STATUS_NO_SUCH_GROUP; } - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); status = pdb_delete_dom_group(p->mem_ctx, group_rid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5435,8 +5474,6 @@ NTSTATUS _samr_DeleteDomAlias(pipes_struct *p, struct samr_DeleteDomAlias *r) { struct samr_alias_info *ainfo; - SE_PRIV se_rights; - bool can_add_accounts; NTSTATUS status; DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__)); @@ -5461,19 +5498,12 @@ NTSTATUS _samr_DeleteDomAlias(pipes_struct *p, DEBUG(10, ("lookup on Local SID\n")); - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); /* Have passdb delete the alias */ status = pdb_delete_alias(&ainfo->sid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5500,8 +5530,6 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p, const char *name; struct samr_domain_info *dinfo; struct samr_group_info *ginfo; - SE_PRIV se_rights; - bool can_add_accounts; dinfo = policy_handle_find(p, r->in.domain_handle, SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL, @@ -5523,20 +5551,12 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p, return status; } - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); /* check that we successfully create the UNIX group */ - status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5571,8 +5591,6 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p, struct samr_alias_info *ainfo; gid_t gid; NTSTATUS result; - SE_PRIV se_rights; - bool can_add_accounts; dinfo = policy_handle_find(p, r->in.domain_handle, SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL, @@ -5586,9 +5604,6 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p, name = r->in.alias_name->string; - se_priv_copy( &se_rights, &se_add_users ); - can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights ); - result = can_create(p->mem_ctx, name); if (!NT_STATUS_IS_OK(result)) { return result; @@ -5596,14 +5611,10 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p, /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_add_accounts ) - become_root(); - + become_root(); /* Have passdb create the alias */ result = pdb_create_alias(name, r->out.rid); - - if ( can_add_accounts ) - unbecome_root(); + unbecome_root(); /******** END SeAddUsers BLOCK *********/ @@ -5622,8 +5633,8 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p, /* check if the group has been successfully created */ if ( getgrgid(gid) == NULL ) { - DEBUG(10, ("getgrgid(%d) of just created alias failed\n", - gid)); + DEBUG(10, ("getgrgid(%u) of just created alias failed\n", + (unsigned int)gid)); return NT_STATUS_ACCESS_DENIED; } @@ -5754,7 +5765,6 @@ NTSTATUS _samr_SetGroupInfo(pipes_struct *p, GROUP_MAP map; NTSTATUS status; bool ret; - bool can_mod_accounts; ginfo = policy_handle_find(p, r->in.group_handle, SAMR_GROUP_ACCESS_SET_INFO, NULL, @@ -5783,17 +5793,11 @@ NTSTATUS _samr_SetGroupInfo(pipes_struct *p, return NT_STATUS_INVALID_INFO_CLASS; } - can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_mod_accounts ) - become_root(); - + become_root(); status = pdb_update_group_mapping_entry(&map); - - if ( can_mod_accounts ) - unbecome_root(); + unbecome_root(); /******** End SeAddUsers BLOCK *********/ @@ -5813,7 +5817,6 @@ NTSTATUS _samr_SetAliasInfo(pipes_struct *p, { struct samr_alias_info *ainfo; struct acct_info info; - bool can_mod_accounts; NTSTATUS status; ainfo = policy_handle_find(p, r->in.alias_handle, @@ -5880,17 +5883,11 @@ NTSTATUS _samr_SetAliasInfo(pipes_struct *p, return NT_STATUS_INVALID_INFO_CLASS; } - can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users ); - /******** BEGIN SeAddUsers BLOCK *********/ - if ( can_mod_accounts ) - become_root(); - + become_root(); status = pdb_set_aliasinfo( &ainfo->sid, &info ); - - if ( can_mod_accounts ) - unbecome_root(); + unbecome_root(); /******** End SeAddUsers BLOCK *********/ @@ -5972,8 +5969,8 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p, se_priv_copy( &se_rights, &se_add_users ); status = access_check_samr_object(psd, p->server_info->ptok, - &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access, - &acc_granted, "_samr_OpenGroup"); + &se_rights, SAMR_GROUP_ACCESS_ADD_MEMBER, + des_access, &acc_granted, "_samr_OpenGroup"); if ( !NT_STATUS_IS_OK(status) ) return status; @@ -6090,18 +6087,33 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p, time_t u_logout; time_t u_lock_duration, u_reset_time; NTSTATUS result; + uint32_t acc_required = 0; DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__)); - /* We do have different access bits for info - * levels here, but we're really just looking for - * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately - * this maps to different specific bits. So - * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1 - * set we are ok. */ + switch (r->in.level) { + case 1: /* DomainPasswordInformation */ + case 12: /* DomainLockoutInformation */ + /* DOMAIN_WRITE_PASSWORD_PARAMETERS */ + acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1; + break; + case 3: /* DomainLogoffInformation */ + case 4: /* DomainOemInformation */ + /* DOMAIN_WRITE_OTHER_PARAMETERS */ + acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2; + break; + case 6: /* DomainReplicationInformation */ + case 9: /* DomainStateInformation */ + case 7: /* DomainServerRoleInformation */ + /* DOMAIN_ADMINISTER_SERVER */ + acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3; + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + } dinfo = policy_handle_find(p, r->in.domain_handle, - SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL, + acc_required, NULL, struct samr_domain_info, &result); if (!NT_STATUS_IS_OK(result)) { return result; @@ -6110,7 +6122,7 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p, DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level)); switch (r->in.level) { - case 0x01: + case 1: u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age); u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age); pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length); @@ -6119,19 +6131,19 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p, 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 0x03: + case 3: 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 0x04: + case 4: break; - case 0x06: + case 6: break; - case 0x07: + case 7: break; - case 0x09: + case 9: break; - case 0x0c: + case 12: u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration); if (u_lock_duration != -1) u_lock_duration /= 60; @@ -6295,6 +6307,36 @@ NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p, return _samr_GetDisplayEnumerationIndex(p, &q); } +/**************************************************************** + _samr_RidToSid +****************************************************************/ + +NTSTATUS _samr_RidToSid(pipes_struct *p, + struct samr_RidToSid *r) +{ + struct samr_domain_info *dinfo; + NTSTATUS status; + struct dom_sid sid; + + dinfo = policy_handle_find(p, r->in.domain_handle, + 0, NULL, + struct samr_domain_info, &status); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) { + return NT_STATUS_NO_MEMORY; + } + + *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid); + if (!*r->out.sid) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + /**************************************************************** ****************************************************************/ @@ -6321,7 +6363,6 @@ NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p, NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p, struct samr_TestPrivateFunctionsDomain *r) { - p->rng_fault_state = true; return NT_STATUS_NOT_IMPLEMENTED; } @@ -6377,16 +6418,6 @@ NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p, /**************************************************************** ****************************************************************/ -NTSTATUS _samr_RidToSid(pipes_struct *p, - struct samr_RidToSid *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - NTSTATUS _samr_SetDsrmPassword(pipes_struct *p, struct samr_SetDsrmPassword *r) {