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); }
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; }
/** * 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; }
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; }
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; } } }
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; }
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; }