示例#1
0
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;
}
示例#2
0
/**
 * 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;
}
示例#3
0
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 {
示例#4
0
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);
}
示例#5
0
文件: uid.c 项目: Arkhont/samba
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;
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
文件: vfs_afsacl.c 项目: gojdic/samba
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;
}
示例#10
0
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);
}