static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, smbacl4_vfs_params *params, uint32_t security_info, TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, struct SMB4ACL_T *theacl) { int good_aces = 0; struct dom_sid sid_owner, sid_group; size_t sd_size = 0; struct security_ace *nt_ace_list = NULL; struct security_acl *psa = NULL; TALLOC_CTX *frame = talloc_stackframe(); bool ok; if (theacl==NULL) { TALLOC_FREE(frame); return NT_STATUS_ACCESS_DENIED; /* special because we * need to think through * the null case.*/ } uid_to_sid(&sid_owner, sbuf->st_ex_uid); gid_to_sid(&sid_group, sbuf->st_ex_gid); ok = smbacl4_nfs42win(frame, params, theacl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_ex_mode), &nt_ace_list, &good_aces); if (!ok) { DEBUG(8,("smbacl4_nfs42win failed\n")); TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } psa = make_sec_acl(frame, NT4_ACL_REVISION, good_aces, nt_ace_list); if (psa == NULL) { DEBUG(2,("make_sec_acl failed\n")); TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } DEBUG(10,("after make sec_acl\n")); *ppdesc = make_sec_desc( mem_ctx, SD_REVISION, smbacl4_get_controlflags(theacl), (security_info & SECINFO_OWNER) ? &sid_owner : NULL, (security_info & SECINFO_GROUP) ? &sid_group : NULL, NULL, psa, &sd_size); if (*ppdesc==NULL) { DEBUG(2,("make_sec_desc failed\n")); TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with " "sd_size %d\n", (int)ndr_size_security_descriptor(*ppdesc, 0))); TALLOC_FREE(frame); return NT_STATUS_OK; }
/** * Turn struct ifs_identity into SID */ static bool onefs_identity_to_sid(struct ifs_identity *id, struct dom_sid *sid) { if (!id || !sid) return false; if (id->type >= IFS_ID_TYPE_LAST) return false; switch (id->type) { case IFS_ID_TYPE_UID: uid_to_sid(sid, id->id.uid); break; case IFS_ID_TYPE_GID: gid_to_sid(sid, id->id.gid); break; case IFS_ID_TYPE_EVERYONE: sid_copy(sid, &global_sid_World); break; case IFS_ID_TYPE_NULL: sid_copy(sid, &global_sid_NULL); break; case IFS_ID_TYPE_CREATOR_OWNER: sid_copy(sid, &global_sid_Creator_Owner); break; case IFS_ID_TYPE_CREATOR_GROUP: sid_copy(sid, &global_sid_Creator_Group); break; default: DEBUG(0, ("Unknown identity type: %d\n", id->type)); return false; } return true; }
static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, SMB_STRUCT_STAT *psbuf, uint32 security_info, struct security_descriptor **ppdesc) { struct security_ace *nt_ace_list; struct dom_sid owner_sid, group_sid; struct security_acl *psa = NULL; int good_aces; size_t sd_size; TALLOC_CTX *mem_ctx = talloc_tos(); struct afs_ace *afs_ace; uid_to_sid(&owner_sid, psbuf->st_ex_uid); gid_to_sid(&group_sid, psbuf->st_ex_gid); if (afs_acl->num_aces) { nt_ace_list = talloc_array(mem_ctx, struct security_ace, afs_acl->num_aces); if (nt_ace_list == NULL) return 0; } else {
static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, SMB_STRUCT_STAT *psbuf) { struct dom_sid owner_sid, group_sid; size_t sd_size; struct security_ace *pace = NULL; struct security_acl *pacl = NULL; uid_to_sid(&owner_sid, psbuf->st_uid); gid_to_sid(&group_sid, psbuf->st_gid); pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2); if (!pace) { return NULL; } init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0); init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0); pacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 2, pace); if (!pacl) { return NULL; } return make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1, SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT, &owner_sid, &group_sid, NULL, pacl, &sd_size); }
static bool change_to_user_internal(connection_struct *conn, const struct auth_serversupplied_info *session_info, uint16_t vuid) { int snum; gid_t gid; uid_t uid; char group_c; int num_groups = 0; gid_t *group_list = NULL; bool ok; snum = SNUM(conn); ok = check_user_ok(conn, vuid, session_info, snum); if (!ok) { DEBUG(2,("SMB user %s (unix user %s) " "not permitted access to share %s.\n", session_info->sanitized_username, session_info->unix_name, lp_servicename(snum))); return false; } uid = conn->session_info->utok.uid; gid = conn->session_info->utok.gid; num_groups = conn->session_info->utok.ngroups; group_list = conn->session_info->utok.groups; /* * See if we should force group for this service. If so this overrides * any group set in the force user code. */ if((group_c = *lp_force_group(snum))) { SMB_ASSERT(conn->force_group_gid != (gid_t)-1); if (group_c == '+') { int i; /* * Only force group if the user is a member of the * service group. Check the group memberships for this * user (we already have this) to see if we should force * the group. */ for (i = 0; i < num_groups; i++) { if (group_list[i] == conn->force_group_gid) { conn->session_info->utok.gid = conn->force_group_gid; gid = conn->force_group_gid; gid_to_sid(&conn->session_info->security_token ->sids[1], gid); break; } } } else { conn->session_info->utok.gid = conn->force_group_gid; gid = conn->force_group_gid; gid_to_sid(&conn->session_info->security_token->sids[1], gid); } } /*Set current_user since we will immediately also call set_sec_ctx() */ current_user.ut.ngroups = num_groups; current_user.ut.groups = group_list; set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, conn->session_info->security_token); current_user.conn = conn; current_user.vuid = vuid; DEBUG(5, ("Impersonated user: uid=(%d,%d), gid=(%d,%d)\n", (int)getuid(), (int)geteuid(), (int)getgid(), (int)getegid())); return true; }
static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, smbacl4_vfs_params *params, SMB4ACL_T *theacl, /* in */ struct dom_sid *psid_owner, /* in */ struct dom_sid *psid_group, /* in */ bool is_directory, /* in */ struct security_ace **ppnt_ace_list, /* out */ int *pgood_aces /* out */ ) { SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)theacl; SMB_ACE4_INT_T *aceint; struct security_ace *nt_ace_list = NULL; int good_aces = 0; DEBUG(10, ("smbacl_nfs42win entered\n")); aclint = get_validated_aclint(theacl); /* We do not check for naces being 0 or theacl being NULL here because it is done upstream in smb_get_nt_acl_nfs4(). We reserve twice the number of input aces because one nfs4 ace might result in 2 nt aces.*/ nt_ace_list = (struct security_ace *)TALLOC_ZERO_SIZE( mem_ctx, 2 * aclint->naces * sizeof(struct security_ace)); if (nt_ace_list==NULL) { DEBUG(10, ("talloc error")); errno = ENOMEM; return false; } for (aceint=aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) { uint32_t mask; struct dom_sid sid; SMB_ACE4PROP_T *ace = &aceint->prop; uint32_t win_ace_flags; DEBUG(10, ("magic: 0x%x, type: %d, iflags: %x, flags: %x, " "mask: %x, who: %d\n", aceint->magic, ace->aceType, ace->flags, ace->aceFlags, ace->aceMask, ace->who.id)); SMB_ASSERT(aceint->magic==SMB_ACE4_INT_MAGIC); if (ace->flags & SMB_ACE4_ID_SPECIAL) { switch (ace->who.special_id) { case SMB_ACE4_WHO_OWNER: sid_copy(&sid, psid_owner); break; case SMB_ACE4_WHO_GROUP: sid_copy(&sid, psid_group); break; case SMB_ACE4_WHO_EVERYONE: sid_copy(&sid, &global_sid_World); break; default: DEBUG(8, ("invalid special who id %d " "ignored\n", ace->who.special_id)); continue; } } else { if (ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) { gid_to_sid(&sid, ace->who.gid); } else { uid_to_sid(&sid, ace->who.uid); } } DEBUG(10, ("mapped %d to %s\n", ace->who.id, sid_string_dbg(&sid))); if (is_directory && (ace->aceMask & SMB_ACE4_ADD_FILE)) { ace->aceMask |= SMB_ACE4_DELETE_CHILD; } if (!is_directory && params->map_full_control) { /* * Do we have all access except DELETE_CHILD * (not caring about the delete bit). */ uint32_t test_mask = ((ace->aceMask|SMB_ACE4_DELETE|SMB_ACE4_DELETE_CHILD) & SMB_ACE4_ALL_MASKS); if (test_mask == SMB_ACE4_ALL_MASKS) { ace->aceMask |= SMB_ACE4_DELETE_CHILD; } } win_ace_flags = map_nfs4_ace_flags_to_windows_ace_flags( ace->aceFlags); if (!is_directory && (win_ace_flags & (SEC_ACE_FLAG_OBJECT_INHERIT| SEC_ACE_FLAG_CONTAINER_INHERIT))) { /* * GPFS sets inherits dir_inhert and file_inherit flags * to files, too, which confuses windows, and seems to * be wrong anyways. ==> Map these bits away for files. */ DEBUG(10, ("removing inherit flags from nfs4 ace\n")); win_ace_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT| SEC_ACE_FLAG_CONTAINER_INHERIT); } DEBUG(10, ("Windows mapped ace flags: 0x%x => 0x%x\n", ace->aceFlags, win_ace_flags)); mask = ace->aceMask; /* Windows clients expect SYNC on acls to correctly allow rename. See bug #7909. */ /* But not on DENY ace entries. See bug #8442. */ if(ace->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE) { mask = ace->aceMask | SMB_ACE4_SYNCHRONIZE; } /* Mapping of owner@ and group@ to creator owner and creator group. Keep old behavior in mode special. */ if (params->mode != e_special && ace->flags & SMB_ACE4_ID_SPECIAL && (ace->who.special_id == SMB_ACE4_WHO_OWNER || ace->who.special_id == SMB_ACE4_WHO_GROUP)) { DEBUG(10, ("Map special entry\n")); if (!(win_ace_flags & SEC_ACE_FLAG_INHERIT_ONLY)) { uint32_t win_ace_flags_current; DEBUG(10, ("Map current sid\n")); win_ace_flags_current = win_ace_flags & ~(SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT); init_sec_ace(&nt_ace_list[good_aces++], &sid, ace->aceType, mask, win_ace_flags_current); } if (ace->who.special_id == SMB_ACE4_WHO_OWNER && win_ace_flags & (SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT)) { uint32_t win_ace_flags_creator; DEBUG(10, ("Map creator owner\n")); win_ace_flags_creator = win_ace_flags | SMB_ACE4_INHERIT_ONLY_ACE; init_sec_ace(&nt_ace_list[good_aces++], &global_sid_Creator_Owner, ace->aceType, mask, win_ace_flags_creator); } if (ace->who.special_id == SMB_ACE4_WHO_GROUP && win_ace_flags & (SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT)) { uint32_t win_ace_flags_creator; DEBUG(10, ("Map creator owner group\n")); win_ace_flags_creator = win_ace_flags | SMB_ACE4_INHERIT_ONLY_ACE; init_sec_ace(&nt_ace_list[good_aces++], &global_sid_Creator_Group, ace->aceType, mask, win_ace_flags_creator); } } else { DEBUG(10, ("Map normal sid\n")); init_sec_ace(&nt_ace_list[good_aces++], &sid, ace->aceType, mask, win_ace_flags); } } nt_ace_list = (struct security_ace *)TALLOC_REALLOC(mem_ctx, nt_ace_list, good_aces * sizeof(struct security_ace)); if (nt_ace_list == NULL) { errno = ENOMEM; return false; } *ppnt_ace_list = nt_ace_list; *pgood_aces = good_aces; return true; }
static size_t afs_to_nt_acl(struct afs_acl *afs_acl, struct files_struct *fsp, uint32 security_info, struct security_descriptor **ppdesc) { SEC_ACE *nt_ace_list; DOM_SID owner_sid, group_sid; SEC_ACCESS mask; SMB_STRUCT_STAT sbuf; SEC_ACL *psa = NULL; int good_aces; size_t sd_size; TALLOC_CTX *mem_ctx = main_loop_talloc_get(); struct afs_ace *afs_ace; if (fsp->is_directory || fsp->fh->fd == -1) { /* Get the stat struct for the owner info. */ if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) { return 0; } } else { if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { return 0; } } uid_to_sid(&owner_sid, sbuf.st_uid); gid_to_sid(&group_sid, sbuf.st_gid); if (afs_acl->num_aces) { nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces); if (nt_ace_list == NULL) return 0; } else { nt_ace_list = NULL; } afs_ace = afs_acl->acelist; good_aces = 0; while (afs_ace != NULL) { uint32 nt_rights; uint8 flag = SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT; if (afs_ace->type == SID_NAME_UNKNOWN) { DEBUG(10, ("Ignoring unknown name %s\n", afs_ace->name)); afs_ace = afs_ace->next; continue; } if (fsp->is_directory) afs_to_nt_dir_rights(afs_ace->rights, &nt_rights, &flag); else nt_rights = afs_to_nt_file_rights(afs_ace->rights); init_sec_access(&mask, nt_rights); init_sec_ace(&nt_ace_list[good_aces++], &(afs_ace->sid), SEC_ACE_TYPE_ACCESS_ALLOWED, mask, flag); afs_ace = afs_ace->next; } psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, good_aces, nt_ace_list); if (psa == NULL) return 0; *ppdesc = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL, (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL, NULL, psa, &sd_size); return sd_size; }
NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx, const char *unix_username, const struct passwd *pwd, struct netr_SamInfo3 **pinfo3, struct extra_auth_info *extra) { struct netr_SamInfo3 *info3; NTSTATUS status; TALLOC_CTX *tmp_ctx; const char *domain_name = NULL; const char *user_name = NULL; struct dom_sid domain_sid; struct dom_sid user_sid; struct dom_sid group_sid; enum lsa_SidType type; uint32_t num_sids = 0; struct dom_sid *user_sids = NULL; bool is_null; bool ok; tmp_ctx = talloc_stackframe(); ok = lookup_name_smbconf(tmp_ctx, unix_username, LOOKUP_NAME_ALL, &domain_name, &user_name, &user_sid, &type); if (!ok) { status = NT_STATUS_NO_SUCH_USER; goto done; } if (type != SID_NAME_USER) { status = NT_STATUS_NO_SUCH_USER; goto done; } ok = winbind_lookup_usersids(tmp_ctx, &user_sid, &num_sids, &user_sids); /* Check if winbind is running */ if (ok) { /* * Winbind is running and the first element of the user_sids * is the primary group. */ if (num_sids > 0) { group_sid = user_sids[0]; } } else { /* * Winbind is not running, try to create the group_sid from the * passwd group id. */ /* * This can lead to a primary group of S-1-22-2-XX which * will be rejected by other Samba code. */ gid_to_sid(&group_sid, pwd->pw_gid); } /* * If we are a unix group, or a wellknown/builtin alias, * set the group_sid to the * 'Domain Users' RID of 513 which will always resolve to a * name. */ if (sid_check_is_in_unix_groups(&group_sid) || sid_check_is_in_builtin(&group_sid) || sid_check_is_in_wellknown_domain(&group_sid)) { if (sid_check_is_in_unix_users(&user_sid)) { sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_RID_USERS); } else { sid_copy(&domain_sid, &user_sid); sid_split_rid(&domain_sid, NULL); sid_compose(&group_sid, &domain_sid, DOMAIN_RID_USERS); } } /* Make sure we have a valid group sid */ is_null = is_null_sid(&group_sid); if (is_null) { status = NT_STATUS_NO_SUCH_USER; goto done; } /* Construct a netr_SamInfo3 from the information we have */ info3 = talloc_zero(tmp_ctx, struct netr_SamInfo3); if (!info3) { status = NT_STATUS_NO_MEMORY; goto done; } info3->base.account_name.string = talloc_strdup(info3, unix_username); if (info3->base.account_name.string == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } ZERO_STRUCT(domain_sid); status = SamInfo3_handle_sids(unix_username, &user_sid, &group_sid, info3, &domain_sid, extra); if (!NT_STATUS_IS_OK(status)) { goto done; } info3->base.domain_sid = dom_sid_dup(info3, &domain_sid); if (info3->base.domain_sid == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } ok = sid_peek_check_rid(&domain_sid, &group_sid, &info3->base.primary_gid); if (!ok) { DEBUG(1, ("The primary group domain sid(%s) does not " "match the domain sid(%s) for %s(%s)\n", sid_string_dbg(&group_sid), sid_string_dbg(&domain_sid), unix_username, sid_string_dbg(&user_sid))); status = NT_STATUS_INVALID_SID; goto done; } info3->base.acct_flags = ACB_NORMAL; if (num_sids) { status = group_sids_to_info3(info3, user_sids, num_sids); if (!NT_STATUS_IS_OK(status)) { goto done; } } *pinfo3 = talloc_steal(mem_ctx, info3); status = NT_STATUS_OK; done: talloc_free(tmp_ctx); return status; }
static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, SMB_STRUCT_STAT *psbuf, uint32 security_info, struct security_descriptor **ppdesc) { SEC_ACE *nt_ace_list; DOM_SID owner_sid, group_sid; SEC_ACL *psa = NULL; int good_aces; size_t sd_size; TALLOC_CTX *mem_ctx = talloc_tos(); struct afs_ace *afs_ace; uid_to_sid(&owner_sid, psbuf->st_uid); gid_to_sid(&group_sid, psbuf->st_gid); if (afs_acl->num_aces) { nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces); if (nt_ace_list == NULL) return 0; } else { nt_ace_list = NULL; } afs_ace = afs_acl->acelist; good_aces = 0; while (afs_ace != NULL) { uint32_t nt_rights; uint8 flag = SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT; if (afs_ace->type == SID_NAME_UNKNOWN) { DEBUG(10, ("Ignoring unknown name %s\n", afs_ace->name)); afs_ace = afs_ace->next; continue; } if (S_ISDIR(psbuf->st_mode)) afs_to_nt_dir_rights(afs_ace->rights, &nt_rights, &flag); else nt_rights = afs_to_nt_file_rights(afs_ace->rights); init_sec_ace(&nt_ace_list[good_aces++], &(afs_ace->sid), SEC_ACE_TYPE_ACCESS_ALLOWED, nt_rights, flag); afs_ace = afs_ace->next; } psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, good_aces, nt_ace_list); if (psa == NULL) return 0; *ppdesc = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL, (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL, NULL, psa, &sd_size); return sd_size; }
BOOL change_to_user(connection_struct *conn, uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); int snum; gid_t gid; uid_t uid; char group_c; BOOL must_free_token = False; NT_USER_TOKEN *token = NULL; if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); return(False); } /* * We need a separate check in security=share mode due to vuid * always being UID_FIELD_INVALID. If we don't do this then * in share mode security we are *always* changing uid's between * SMB's - this hurts performance - Badly. */ if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && (current_user.ut.uid == conn->uid)) { DEBUG(4,("change_to_user: Skipping user change - already " "user\n")); return(True); } else if ((current_user.conn == conn) && (vuser != 0) && (current_user.vuid == vuid) && (current_user.ut.uid == vuser->uid)) { DEBUG(4,("change_to_user: Skipping user change - already " "user\n")); return(True); } snum = SNUM(conn); if ((vuser) && !check_user_ok(conn, vuser, snum)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", vuser->user.smb_name, vuser->user.unix_name, vuid, lp_servicename(snum))); return False; } if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; current_user.ut.groups = conn->groups; current_user.ut.ngroups = conn->ngroups; token = conn->nt_user_token; } else if (vuser) { uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; current_user.ut.ngroups = vuser->n_groups; current_user.ut.groups = vuser->groups; token = vuser->nt_user_token; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); return False; } /* * See if we should force group for this service. * If so this overrides any group set in the force * user code. */ if((group_c = *lp_force_group(snum))) { token = dup_nt_token(NULL, token); if (token == NULL) { DEBUG(0, ("dup_nt_token failed\n")); return False; } must_free_token = True; if(group_c == '+') { /* * Only force group if the user is a member of * the service group. Check the group memberships for * this user (we already have this) to * see if we should force the group. */ int i; for (i = 0; i < current_user.ut.ngroups; i++) { if (current_user.ut.groups[i] == conn->gid) { gid = conn->gid; gid_to_sid(&token->user_sids[1], gid); break; } } } else { gid = conn->gid; gid_to_sid(&token->user_sids[1], gid); } } set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, token); /* * Free the new token (as set_sec_ctx copies it). */ if (must_free_token) TALLOC_FREE(token); current_user.conn = conn; current_user.vuid = vuid; DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); return(True); }