Beispiel #1
0
void *talloc_realloc_array(TALLOC_CTX *ctx, void *ptr, size_t el_size, unsigned int count)
#endif
{
        if (count >= MAX_TALLOC_SIZE/el_size) {
                return NULL;
        }
	return TALLOC_REALLOC(ctx, ptr, el_size * count);
}
Beispiel #2
0
static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
{
	DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath);

	shadow_copy_data->num_volumes = 0;
	shadow_copy_data->labels = NULL;

	if (!p) {
		DEBUG(0,("shadow_copy_get_shadow_copy_data: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fsp->conn->connectpath));
		return -1;
	}

	while (True) {
		SHADOW_COPY_LABEL *tlabels;
		SMB_STRUCT_DIRENT *d;

		d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p);
		if (d == NULL) {
			break;
		}

		/* */
		if (!shadow_copy_match_name(d->d_name)) {
			DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore [%s]\n",d->d_name));
			continue;
		}

		DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore [%s]\n",d->d_name));

		if (!labels) {
			shadow_copy_data->num_volumes++;
			continue;
		}

		tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(shadow_copy_data->mem_ctx,
									shadow_copy_data->labels,
									(shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL));
		if (tlabels == NULL) {
			DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of memory\n"));
			SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p);
			return -1;
		}

		snprintf(tlabels[shadow_copy_data->num_volumes++], sizeof(*tlabels), "%s",d->d_name);

		shadow_copy_data->labels = tlabels;
	}

	SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p);
	return 0;
}
Beispiel #3
0
/**
 * Realloc @p s to append the formatted result of @p fmt and @p ap,
 * and return @p s, which may have moved.  Good for gradually
 * accumulating output into a string buffer.
 **/
 char *talloc_vasprintf_append(TALLOC_CTX *t, char *s,
			       const char *fmt, va_list ap)
{	
	int len, s_len;
	va_list ap2;

	VA_COPY(ap2, ap);

	s_len = strlen(s);
	len = vsnprintf(NULL, 0, fmt, ap2);

	s = TALLOC_REALLOC(t, s, s_len + len+1);
	if (!s) return NULL;

	VA_COPY(ap2, ap);

	vsnprintf(s+s_len, len+1, fmt, ap2);

	return s;
}
Beispiel #4
0
static bool flatten_message(struct notify_queue *q)
{
	struct spoolss_notify_msg *msg = q->msg;
	uint8 *buf = NULL;
	size_t buflen = 0, len;

again:
	len = 0;

	/* Pack header */

	len += tdb_pack(buf + len, buflen - len, "f", msg->printer);

	len += tdb_pack(buf + len, buflen - len, "ddddddd",
			(uint32)q->tv.tv_sec, (uint32)q->tv.tv_usec,
			msg->type, msg->field, msg->id, msg->len, msg->flags);

	/* Pack data */

	if (msg->len == 0)
		len += tdb_pack(buf + len, buflen - len, "dd",
				msg->notify.value[0], msg->notify.value[1]);
	else
		len += tdb_pack(buf + len, buflen - len, "B",
				msg->len, msg->notify.data);

	if (buflen != len) {
		buf = (uint8 *)TALLOC_REALLOC(send_ctx, buf, len);
		if (!buf)
			return False;
		buflen = len;
		goto again;
	}

	q->buf = buf;
	q->buflen = buflen;

	return True;
}
Beispiel #5
0
size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
			       void const *src, size_t srclen, void *dst, BOOL allow_bad_conv)
{
	size_t i_len, o_len, destlen = (srclen * 3) / 2;
	size_t retval;
	const char *inbuf = (const char *)src;
	char *outbuf = NULL, *ob = NULL;
	smb_iconv_t descriptor;
	void **dest = (void **)dst;

	*dest = NULL;

	if (src == NULL || srclen == (size_t)-1)
		return (size_t)-1;
	if (srclen == 0)
		return 0;

	lazy_initialize_conv();

	descriptor = conv_handles[from][to];

	if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
		if (!conv_silent)
			DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));
		return (size_t)-1;
	}

  convert:

	/* +2 is for ucs2 null termination. */
	if ((destlen*2)+2 < destlen) {
		/* wrapped ! abort. */
		if (!conv_silent)
			DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
		if (!ctx)
			SAFE_FREE(outbuf);
		return (size_t)-1;
	} else {
		destlen = destlen * 2;
	}

	/* +2 is for ucs2 null termination. */
	if (ctx) {
		ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
	} else {
		ob = (char *)SMB_REALLOC(ob, destlen + 2);
	}

	if (!ob) {
		DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
		return (size_t)-1;
	}
	outbuf = ob;
	i_len = srclen;
	o_len = destlen;

 again:

	retval = smb_iconv(descriptor,
			   &inbuf, &i_len,
			   &outbuf, &o_len);
	if(retval == (size_t)-1) 		{
	    	const char *reason="unknown error";
		switch(errno) {
			case EINVAL:
				reason="Incomplete multibyte sequence";
				if (!conv_silent)
					DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
				if (allow_bad_conv)
					goto use_as_is;
				break;
			case E2BIG:
				goto convert;		
			case EILSEQ:
				reason="Illegal multibyte sequence";
				if (!conv_silent)
					DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
				if (allow_bad_conv)
					goto use_as_is;
				break;
		}
		if (!conv_silent)
			DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
		/* smb_panic(reason); */
		return (size_t)-1;
	}

  out:

	destlen = destlen - o_len;
	if (ctx) {
		/* We're shrinking here so we know the +2 is safe from wrap. */
		ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
	} else {
		ob = (char *)SMB_REALLOC(ob,destlen + 2);
	}

	if (destlen && !ob) {
		DEBUG(0, ("convert_string_allocate: out of memory!\n"));
		return (size_t)-1;
	}

	*dest = ob;

	/* Must ucs2 null terminate in the extra space we allocated. */
	ob[destlen] = '\0';
	ob[destlen+1] = '\0';

	return destlen;

 use_as_is:

	/* 
	 * Conversion not supported. This is actually an error, but there are so
	 * many misconfigured iconv systems and smb.conf's out there we can't just
	 * fail. Do a very bad conversion instead.... JRA.
	 */

	{
		if (o_len == 0 || i_len == 0)
			goto out;

		if (((from == CH_UTF16LE)||(from == CH_UTF16BE)) &&
				((to != CH_UTF16LE)||(to != CH_UTF16BE))) {
			/* Can't convert from utf16 any endian to multibyte.
			   Replace with the default fail char.
			*/

			if (i_len < 2)
				goto out;

			if (i_len >= 2) {
				*outbuf = lp_failed_convert_char();

				outbuf++;
				o_len--;

				inbuf += 2;
				i_len -= 2;
			}

			if (o_len == 0 || i_len == 0)
				goto out;

			/* Keep trying with the next char... */
			goto again;

		} else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
			/* Can't convert to UTF16LE - just widen by adding the
			   default fail char then zero.
			*/
			if (o_len < 2)
				goto out;

			outbuf[0] = lp_failed_convert_char();
			outbuf[1] = '\0';

			inbuf++;
			i_len--;

			outbuf += 2;
			o_len -= 2;

			if (o_len == 0 || i_len == 0)
				goto out;

			/* Keep trying with the next char... */
			goto again;

		} else if (from != CH_UTF16LE && from != CH_UTF16BE &&
				to != CH_UTF16LE && to != CH_UTF16BE) {
			/* Failed multibyte to multibyte. Just copy the default fail char and
			   try again. */
			outbuf[0] = lp_failed_convert_char();

			inbuf++;
			i_len--;

			outbuf++;
			o_len--;

			if (o_len == 0 || i_len == 0)
				goto out;

			/* Keep trying with the next char... */
			goto again;

		} else {
			/* Keep compiler happy.... */
			goto out;
		}
	}
}
Beispiel #6
0
static int
onefs_shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle,
				       files_struct *fsp,
				       SHADOW_COPY_DATA *shadow_copy_data,
				       bool labels)
{
	void *p = osc_version_opendir();
	char *snap_component = NULL;
	shadow_copy_data->num_volumes = 0;
	shadow_copy_data->labels = NULL;

	if (!p) {
		DEBUG(0, ("shadow_copy_get_shadow_copy_data: osc_opendir() "
			  "failed for [%s]\n",fsp->conn->connectpath));
		return -1;
	}

	while (true) {
		SHADOW_COPY_LABEL *tlabels;
		char *d;

		d = osc_version_readdir(p);
		if (d == NULL)
			break;

		if (!shadow_copy_match_name(d, &snap_component)) {
			DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore "
				  "[%s]\n",d));
			continue;
		}

		DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore "
			 "[%s]\n",d));

		if (!labels) {
			shadow_copy_data->num_volumes++;
			continue;
		}

		tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(
			shadow_copy_data->mem_ctx,
			shadow_copy_data->labels,
			(shadow_copy_data->num_volumes+1) *
			sizeof(SHADOW_COPY_LABEL));

		if (tlabels == NULL) {
			DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of "
				 "memory\n"));
			osc_version_closedir(p);
			return -1;
		}

		snprintf(tlabels[shadow_copy_data->num_volumes++],
			 sizeof(*tlabels), "%s",d);

		shadow_copy_data->labels = tlabels;
	}

	osc_version_closedir(p);

	return 0;
}
Beispiel #7
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;
}