Beispiel #1
0
/*
  try to send the message
*/
static NTSTATUS try_send(struct imessaging_rec *rec)
{
	struct imessaging_context *msg = rec->msg;
	size_t nsent;
	void *priv;
	NTSTATUS status;
	struct socket_address *path;

	/* rec->path is the path of the *other* socket, where we want
	 * this to end up */
	path = socket_address_from_strings(msg, msg->sock->backend_name, 
					   rec->path, 0);
	if (!path) {
		return NT_STATUS_NO_MEMORY;
	}

	/* we send with privileges so messages work from any context */
	priv = root_privileges();
	status = socket_sendto(msg->sock, &rec->packet, &nsent, path);
	talloc_free(path);
	talloc_free(priv);

	return status;
}
Beispiel #2
0
/*
  save the acl for a file into system.nfs4acl
*/
static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
				   struct security_descriptor *sd)
{
	NTSTATUS status;
	void *privs;
	struct nfs4acl acl;
	int i;
	TALLOC_CTX *tmp_ctx;
	struct id_map *ids;

	tmp_ctx = talloc_new(pvfs);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	acl.a_version = 0;
	acl.a_flags   = sd->type;
	acl.a_count   = sd->dacl?sd->dacl->num_aces:0;
	acl.a_owner_mask = 0;
	acl.a_group_mask = 0;
	acl.a_other_mask = 0;

	acl.ace = talloc_array(tmp_ctx, struct nfs4ace, acl.a_count);
	if (!acl.ace) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	ids = talloc_array(tmp_ctx, struct id_map, acl.a_count);
	if (ids == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	for (i=0;i<acl.a_count;i++) {
		struct security_ace *ace = &sd->dacl->aces[i];
		ZERO_STRUCT(ids[i].xid);
		ids[i].sid = dom_sid_dup(ids, &ace->trustee);
		if (ids[i].sid == NULL) {
			talloc_free(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}
		ids[i].status = ID_UNKNOWN;
	}

	status = wbc_sids_to_xids(ids, acl.a_count);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(tmp_ctx);
		return status;
	}

	for (i=0;i<acl.a_count;i++) {
		struct nfs4ace *a = &acl.ace[i];
		struct security_ace *ace = &sd->dacl->aces[i];
		a->e_type  = ace->type;
		a->e_flags = ace->flags;
		a->e_mask  = ace->access_mask;
		if (ids[i].xid.type != ID_TYPE_UID) {
			a->e_flags |= ACE4_IDENTIFIER_GROUP;
		}
		a->e_id = ids[i].xid.id;
		a->e_who   = "";
	}

	privs = root_privileges();
	status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, 
				     NFS4ACL_XATTR_NAME, 
				     &acl, (void *) ndr_push_nfs4acl);
	talloc_free(privs);

	talloc_free(tmp_ctx);
	return status;
}
Beispiel #3
0
/*
  become root, and change directory to the directory component of a
  path. Return a talloc context which when freed will move us back
  to the original directory, and return us to the original uid

  change the pathname argument to contain just the base component of
  the path

  return NULL on error, which could include an attempt to subvert
  security using symlink tricks
 */
static struct pvfs_sys_ctx *pvfs_sys_pushdir(struct pvfs_state *pvfs,
					     const char **pathname)
{
	struct pvfs_sys_ctx *ctx;
	char *cwd, *p, *dirname;
	int ret;

	ctx = talloc_zero(pvfs, struct pvfs_sys_ctx);
	if (ctx == NULL) {
		return NULL;
	}
	ctx->pvfs = pvfs;
	ctx->privs = root_privileges();
	if (ctx->privs == NULL) {
		talloc_free(ctx);
		return NULL;
	}

	talloc_steal(ctx, ctx->privs);

	if (!pathname) {
		/* no pathname needed */
		return ctx;
	}

	p = strrchr(*pathname, '/');
	if (p == NULL) {
		/* we don't need to change directory */
		return ctx;
	}

	/* we keep the old st around, so we can tell that
	   we have come back to the right directory */
	if (stat(".", &ctx->st_orig) != 0) {
		talloc_free(ctx);
		return NULL;
	}

	cwd = get_current_dir_name();
	if (cwd == NULL) {
		talloc_free(ctx);
		return NULL;
	}

	ctx->old_wd = talloc_strdup(ctx, cwd);
	free(cwd);

	if (ctx->old_wd == NULL) {
		talloc_free(ctx);
		return NULL;
	}

	dirname = talloc_strndup(ctx, *pathname, (p - *pathname));
	if (dirname == NULL) {
		talloc_free(ctx);
		return NULL;
	}

	ret = pvfs_sys_chdir_nosymlink(ctx, *pathname);
	if (ret == -1) {
		talloc_free(ctx);
		return NULL;
	}

	talloc_set_destructor(ctx, pvfs_sys_pushdir_destructor);

	/* return the basename as the filename that should be operated on */
	(*pathname) = talloc_strdup(ctx, p+1);
	if (! *pathname) {
		talloc_free(ctx);
		return NULL;
	}

	return ctx;
}