static uint32_t _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb, int keyval, char **retbuf, uint32_t buffer_size) { TDB_DATA kbuf, dbuf; char temp[PERFCOUNT_MAX_LEN] = {0}; char *buf1 = *retbuf; uint32_t working_size = 0; DATA_BLOB name_index, name; bool ok; snprintf(temp, sizeof(temp), "%d", keyval); kbuf = string_tdb_data(temp); dbuf = tdb_fetch(tdb, kbuf); if(dbuf.dptr == NULL) { /* If a key isn't there, just bypass it -- this really shouldn't happen unless someone's mucking around with the tdb */ DEBUG(3, ("_reg_perfcount_multi_sz_from_tdb: failed to find key [%s] in [%s].\n", temp, tdb_name(tdb))); return buffer_size; } /* First encode the name_index */ working_size = (kbuf.dsize + 1)*sizeof(uint16_t); buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size); if(!buf1) { buffer_size = 0; return buffer_size; } ok = push_reg_sz(talloc_tos(), &name_index, (const char *)kbuf.dptr); if (!ok) { buffer_size = 0; return buffer_size; } memcpy(buf1+buffer_size, (char *)name_index.data, working_size); buffer_size += working_size; /* Now encode the actual name */ working_size = (dbuf.dsize + 1)*sizeof(uint16_t); buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size); if(!buf1) { buffer_size = 0; return buffer_size; } memset(temp, 0, sizeof(temp)); memcpy(temp, dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); ok = push_reg_sz(talloc_tos(), &name, temp); if (!ok) { buffer_size = 0; return buffer_size; } memcpy(buf1+buffer_size, (char *)name.data, working_size); buffer_size += working_size; *retbuf = buf1; return buffer_size; }
static struct group *nss_getgrgid(gid_t gid) { NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *, size_t , int *) = find_fn("getgrgid_r"); static struct group grp; static char *buf; static int buflen = 1000; NSS_STATUS status; if (!_nss_getgrgid_r) return NULL; if (!buf) buf = SMB_MALLOC(buflen); again: status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno); if (status == NSS_STATUS_TRYAGAIN) { buflen *= 2; buf = SMB_REALLOC(buf, buflen); if (!buf) { return NULL; } goto again; } if (status == NSS_STATUS_NOTFOUND) { return NULL; } if (status != NSS_STATUS_SUCCESS) { report_nss_error("getgrgid", status); return NULL; } return &grp; }
static struct smb_acl_t *smb_acl_to_internal(acl_t acl) { struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t); int entry_id = ACL_FIRST_ENTRY; acl_entry_t e; if (result == NULL) { return NULL; } ZERO_STRUCTP(result); while (acl_get_entry(acl, entry_id, &e) == 1) { entry_id = ACL_NEXT_ENTRY; result = (struct smb_acl_t *)SMB_REALLOC( result, sizeof(struct smb_acl_t) + (sizeof(struct smb_acl_entry) * (result->count+1))); if (result == NULL) { DEBUG(0, ("SMB_REALLOC failed\n")); errno = ENOMEM; return NULL; } if (!smb_ace_to_internal(e, &result->acl[result->count])) { SAFE_FREE(result); return NULL; } result->count += 1; } return result; }
bool prs_grow(prs_struct *ps, uint32 extra_space) { uint32 new_size; ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space); if(ps->data_offset + extra_space <= ps->buffer_size) return True; /* * We cannot grow the buffer if we're not reading * into the prs_struct, or if we don't own the memory. */ if(UNMARSHALLING(ps) || !ps->is_dynamic) { DEBUG(0,("prs_grow: Buffer overflow - unable to expand buffer by %u bytes.\n", (unsigned int)extra_space)); return False; } /* * Decide how much extra space we really need. */ extra_space -= (ps->buffer_size - ps->data_offset); if(ps->buffer_size == 0) { /* * Start with 128 bytes (arbitrary value), enough for small rpc * requests */ new_size = MAX(128, extra_space); if((ps->data_p = (char *)SMB_MALLOC(new_size)) == NULL) { DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size)); return False; } memset(ps->data_p, '\0', (size_t)new_size ); } else { /* * If the current buffer size is bigger than the space needed, * just double it, else add extra_space. Always keep 64 bytes * more, so that after we added a large blob we don't have to * realloc immediately again. */ new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space + 64); if ((ps->data_p = (char *)SMB_REALLOC(ps->data_p, new_size)) == NULL) { DEBUG(0,("prs_grow: Realloc failure for size %u.\n", (unsigned int)new_size)); return False; } memset(&ps->data_p[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size)); } ps->buffer_size = new_size; return True; }
bool prs_set_buffer_size(prs_struct *ps, uint32 newsize) { if (newsize > ps->buffer_size) return prs_force_grow(ps, newsize - ps->buffer_size); if (newsize < ps->buffer_size) { ps->buffer_size = newsize; /* newsize == 0 acts as a free and set pointer to NULL */ if (newsize == 0) { SAFE_FREE(ps->data_p); } else { ps->data_p = (char *)SMB_REALLOC(ps->data_p, newsize); if (ps->data_p == NULL) { DEBUG(0,("prs_set_buffer_size: Realloc failure for size %u.\n", (unsigned int)newsize)); DEBUG(0,("prs_set_buffer_size: Reason %s\n",strerror(errno))); return False; } } } return True; }
void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size) #endif { struct talloc_chunk *tc; void *new_ptr; /* size zero is equivalent to free() */ if (!t || size == 0) return NULL; /* realloc(NULL) is equavalent to malloc() */ if (ptr == NULL) return TALLOC(t, size); for (tc=t->list; tc; tc=tc->next) { if (tc->ptr == ptr) { new_ptr = SMB_REALLOC(ptr, size); if (new_ptr) { t->total_alloc_size += (size - tc->size); tc->size = size; tc->ptr = new_ptr; } return new_ptr; } } return NULL; }
char *escape_ldap_string_alloc(const char *s) { size_t len = strlen(s)+1; char *output = SMB_MALLOC(len); char *output_tmp; const char *sub; int i = 0; char *p = output; while (*s) { switch (*s) { case '*': sub = "\\2a"; break; case '(': sub = "\\28"; break; case ')': sub = "\\29"; break; case '\\': sub = "\\5c"; break; default: sub = NULL; break; } if (sub) { len = len + 3; output_tmp = SMB_REALLOC(output, len); if (!output_tmp) { SAFE_FREE(output); return NULL; } output = output_tmp; p = &output[i]; strncpy (p, sub, 3); p += 3; i += 3; } else { *p = *s; p++; i++; } s++; } *p = '\0'; return output; }
enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state *state) { struct winbindd_domain *domain; int total_entries = 0, extra_data_len = 0; char *ted, *extra_data = NULL; DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); /* We need to refresh the trusted domain list as the domains may have changed since we last looked. There may be a sequence number or something we should use but I haven't found it yet. */ if (!init_domain_list()) { DEBUG(1, ("winbindd_list_trusted_domains: could not " "refresh trusted domain list\n")); return WINBINDD_ERROR; } for(domain = domain_list(); domain; domain = domain->next) { /* Skip own domain */ if (domain->primary) continue; /* Add domain to list */ total_entries++; ted = SMB_REALLOC(extra_data, sizeof(fstring) * total_entries); if (!ted) { DEBUG(0,("winbindd_list_trusted_domains: failed to enlarge buffer!\n")); SAFE_FREE(extra_data); return WINBINDD_ERROR; } else extra_data = ted; memcpy(&extra_data[extra_data_len], domain->name, strlen(domain->name)); extra_data_len += strlen(domain->name); extra_data[extra_data_len++] = ','; } if (extra_data) { if (extra_data_len > 1) extra_data[extra_data_len - 1] = '\0'; state->response.extra_data = extra_data; state->response.length += extra_data_len; } return WINBINDD_OK; }
/* * convert either the access or the default part of a * soaris acl to the SMB_ACL format. */ static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count, SMB_ACL_TYPE_T type) { SMB_ACL_T result; int i; if ((result = sys_acl_init(0)) == NULL) { DEBUG(10, ("error allocating memory for SMB_ACL\n")); goto fail; } for (i = 0; i < count; i++) { SMB_ACL_ENTRY_T smb_entry; SMB_ACL_PERM_T smb_perm; if (!_IS_OF_TYPE(solaris_acl[i], type)) { continue; } result = SMB_REALLOC(result, sizeof(struct smb_acl_t) + (sizeof(struct smb_acl_entry) * (result->count + 1))); if (result == NULL) { DEBUG(10, ("error reallocating memory for SMB_ACL\n")); goto fail; } smb_entry = &result->acl[result->count]; if (sys_acl_set_tag_type(smb_entry, solaris_tag_to_smb_tag(solaris_acl[i].a_type)) != 0) { DEBUG(10, ("invalid tag type given: 0x%04x\n", solaris_acl[i].a_type)); goto fail; } /* intentionally not checking return code here: */ sys_acl_set_qualifier(smb_entry, (void *)&solaris_acl[i].a_id); smb_perm = solaris_perm_to_smb_perm(solaris_acl[i].a_perm); if (sys_acl_set_permset(smb_entry, &smb_perm) != 0) { DEBUG(10, ("invalid permset given: %d\n", solaris_acl[i].a_perm)); goto fail; } result->count += 1; } goto done; fail: SAFE_FREE(result); done: DEBUG(10, ("solaris_acl_to_smb_acl %s\n", ((result == NULL) ? "failed" : "succeeded"))); return result; }
/* write to the ASN1 buffer, advancing the buffer pointer */ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { data->data = SMB_REALLOC(data->data, data->ofs+len); if (!data->data) { data->has_error = True; return False; } data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); data->ofs += len; return True; }
uint32_t reg_perfcount_get_counter_names(uint32_t base_index, char **retbuf) { char *buf1 = NULL; uint32_t buffer_size = 0; TDB_CONTEXT *names; char *fname; int i; if (base_index == 0) { return 0; } fname = counters_directory(NAMES_DB); if (fname == NULL) { return 0; } names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444); if (names == NULL) { DEBUG(1, ("reg_perfcount_get_counter_names: unable to open [%s].\n", fname)); TALLOC_FREE(fname); return 0; } TALLOC_FREE(fname); buffer_size = _reg_perfcount_multi_sz_from_tdb(names, 1, retbuf, buffer_size); for(i = 1; i <= base_index; i++) { buffer_size = _reg_perfcount_multi_sz_from_tdb(names, i*2, retbuf, buffer_size); } tdb_close(names); /* Now terminate the MULTI_SZ with a double unicode NULL */ buf1 = *retbuf; buf1 = (char *)SMB_REALLOC(buf1, buffer_size + 2); if(!buf1) { buffer_size = 0; } else { buf1[buffer_size++] = '\0'; buf1[buffer_size++] = '\0'; } *retbuf=buf1; return buffer_size; }
char *file_pload(char *syscmd, size_t *size) { int fd, n; char *p; pstring buf; size_t total; fd = sys_popen(syscmd); if (fd == -1) { return NULL; } p = NULL; total = 0; while ((n = read(fd, buf, sizeof(buf))) > 0) { p = (char *)SMB_REALLOC(p, total + n + 1); if (!p) { DEBUG(0,("file_pload: failed to expand buffer!\n")); close(fd); return NULL; } memcpy(p+total, buf, n); total += n; } if (p) { p[total] = 0; } /* FIXME: Perhaps ought to check that the command completed * successfully (returned 0); if not the data may be * truncated. */ sys_pclose(fd); if (size) { *size = total; } return p; }
bool prs_force_grow(prs_struct *ps, uint32 extra_space) { uint32 new_size = ps->buffer_size + extra_space; if(!UNMARSHALLING(ps) || !ps->is_dynamic) { DEBUG(0,("prs_force_grow: Buffer overflow - unable to expand buffer by %u bytes.\n", (unsigned int)extra_space)); return False; } if((ps->data_p = (char *)SMB_REALLOC(ps->data_p, new_size)) == NULL) { DEBUG(0,("prs_force_grow: Realloc failure for size %u.\n", (unsigned int)new_size)); return False; } memset(&ps->data_p[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size)); ps->buffer_size = new_size; return True; }
void add_session_user(const char *user) { fstring suser; struct passwd *passwd; if (!(passwd = Get_Pwnam(user))) return; fstrcpy(suser,passwd->pw_name); if(!*suser) return; if( session_userlist && in_list(suser,session_userlist,False) ) return; if( !session_userlist || (strlen(suser) + strlen(session_userlist) + 2 >= len_session_userlist) ) { char *newlist; if (len_session_userlist > 128 * PSTRING_LEN) { DEBUG(3,("add_session_user: session userlist already too large.\n")); return; } newlist = SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN ); if( newlist == NULL ) { DEBUG(1,("Unable to resize session_userlist\n")); return; } if (!session_userlist) { *newlist = '\0'; } session_userlist = newlist; len_session_userlist += PSTRING_LEN; } safe_strcat(session_userlist," ",len_session_userlist-1); safe_strcat(session_userlist,suser,len_session_userlist-1); }
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; } } }
int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { char *p; int received = 0; BOOL first = True; char status[21]; int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; int num_received = 0; int i; char *dirlist = NULL; pstring mask; ZERO_ARRAY(status); pstrcpy(mask,Mask); while (1) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBsearch); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,num_asked); SSVAL(cli->outbuf,smb_vwv1,attribute); p = smb_buf(cli->outbuf); *p++ = 4; p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE); *p++ = 5; if (first) { SSVAL(p,0,0); p += 2; } else { SSVAL(p,0,21); p += 2; memcpy(p,status,21); p += 21; } cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) break; received = SVAL(cli->inbuf,smb_vwv0); if (received <= 0) break; first = False; dirlist = (char *)SMB_REALLOC( dirlist,(num_received + received)*DIR_STRUCT_SIZE); if (!dirlist) { DEBUG(0,("cli_list_old: failed to expand dirlist")); return 0; } p = smb_buf(cli->inbuf) + 3; memcpy(dirlist+num_received*DIR_STRUCT_SIZE, p,received*DIR_STRUCT_SIZE); memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); num_received += received; if (cli_is_error(cli)) break; } if (!first) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf, smb_vwv0, 0); /* find count? */ SSVAL(cli->outbuf, smb_vwv1, attribute); p = smb_buf(cli->outbuf); *p++ = 4; fstrcpy(p, ""); p += strlen(p) + 1; *p++ = 5; SSVAL(p, 0, 21); p += 2; memcpy(p,status,21); p += 21; cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { DEBUG(0,("Error closing search: %s\n",cli_errstr(cli))); } } for (p=dirlist,i=0;i<num_received;i++) { file_info finfo; p += interpret_short_filename(cli, p,&finfo); fn("\\", &finfo, Mask, state); } SAFE_FREE(dirlist); return(num_received); }
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { #if 1 int max_matches = 1366; /* Match W2k - was 512. */ #else int max_matches = 512; #endif int info_level; char *p, *p2; pstring mask; file_info finfo; int i; char *dirlist = NULL; int dirlist_len = 0; int total_received = -1; BOOL First = True; int ff_searchcount=0; int ff_eos=0; int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; unsigned int param_len, data_len; uint16 setup; pstring param; const char *mnt; uint32 resume_key = 0; uint32 last_name_raw_len = 0; DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring)); /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; pstrcpy(mask,Mask); while (ff_eos == 0) { loop_count++; if (loop_count > 200) { DEBUG(0,("Error: Looping in FIND_NEXT??\n")); break; } if (First) { setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); /* For W2K servers serving out FAT filesystems we *must* set the resume key. If it's not FAT then it's returned as zero. */ SIVAL(param,6,resume_key); /* ff_resume_key */ /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) { memcpy(p, last_name_raw.data, last_name_raw_len); p += last_name_raw_len; } else { p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } } param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, 0, #if 0 /* w2k value. */ MIN(16384,cli->max_xmit) /* data, length, max. */ #else cli->max_xmit /* data, length, max. */ #endif )) { break; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { /* We need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; SAFE_FREE(rdata); SAFE_FREE(rparam); cli_dos_error(cli, &eclass, &ecode); /* * OS/2 might return "no more files", * which just tells us, that searchcount is zero * in this search. * Guenter Kukkukk <*****@*****.**> */ if (eclass == ERRDOS && ecode == ERRnofiles) { ff_searchcount = 0; cli_reset_error(cli); break; } if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); continue; } if (cli_is_error(cli) || !rdata || !rparam) { SAFE_FREE(rdata); SAFE_FREE(rparam); break; } if (total_received == -1) total_received = 0; /* parse out some important return info */ p = rparam; if (First) { ff_dir_handle = SVAL(p,0); ff_searchcount = SVAL(p,2); ff_eos = SVAL(p,4); } else { ff_searchcount = SVAL(p,0); ff_eos = SVAL(p,2); } if (ff_searchcount == 0) { SAFE_FREE(rdata); SAFE_FREE(rparam); break; } /* point to the data bytes */ p = rdata; /* we might need the lastname for continuations */ for (p2=p,i=0;i<ff_searchcount;i++) { if ((info_level == 260) && (i == ff_searchcount-1)) { /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } p2 += interpret_long_filename(cli,info_level,p2,&finfo, &resume_key,&last_name_raw,&last_name_raw_len); if (!First && *mask && strcsequal(finfo.name, mask)) { DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n", finfo.name)); ff_eos = 1; break; } } if (ff_searchcount > 0) { pstrcpy(mask, finfo.name); } else { pstrcpy(mask,""); } /* grab the data for later use */ /* and add them to the dirlist pool */ dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len); if (!dirlist) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); SAFE_FREE(rdata); SAFE_FREE(rparam); break; } memcpy(dirlist+dirlist_len,p,data_len); dirlist_len += data_len; total_received += ff_searchcount; SAFE_FREE(rdata); SAFE_FREE(rparam); DEBUG(3,("received %d entries (eos=%d)\n", ff_searchcount,ff_eos)); if (ff_searchcount > 0) loop_count = 0; First = False; } mnt = cli_cm_get_mntpoint( cli ); /* see if the server disconnected or the connection otherwise failed */ if (cli_is_error(cli)) { total_received = -1; } else { /* no connection problem. let user function add each entry */ for (p=dirlist,i=0;i<total_received;i++) { p += interpret_long_filename(cli, info_level, p, &finfo,NULL,NULL,NULL); fn( mnt,&finfo, Mask, state ); } } /* free up the dirlist buffer and last name raw blob */ SAFE_FREE(dirlist); data_blob_free(&last_name_raw); return(total_received); }
static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL_CTR *values ) { char *buffer = NULL; int buffer_size = 0; int i, length; char *filename; UNISTR2 data; filename = dos_basename( info3->driverpath ); init_unistr2( &data, filename, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); filename = dos_basename( info3->configfile ); init_unistr2( &data, filename, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); filename = dos_basename( info3->datafile ); init_unistr2( &data, filename, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); filename = dos_basename( info3->helpfile ); init_unistr2( &data, filename, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion, sizeof(info3->cversion) ); if ( info3->dependentfiles ) { /* place the list of dependent files in a single character buffer, separating each file name by a NULL */ for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) { /* strip the path to only the file's base name */ filename = dos_basename( info3->dependentfiles[i] ); length = strlen(filename); buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) ); if ( !buffer ) { break; } init_unistr2( &data, filename, UNI_STR_TERMINATE); memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); buffer_size += (length + 1)*sizeof(uint16); } /* terminated by double NULL. Add the final one here */ buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 ); if ( !buffer ) { buffer_size = 0; } else { buffer[buffer_size++] = '\0'; buffer[buffer_size++] = '\0'; } } regval_ctr_addvalue( values, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size ); SAFE_FREE( buffer ); return; }
char *fgets_slash(char *s2,int maxlen,XFILE *f) { char *s=s2; int len = 0; int c; BOOL start_of_line = True; if (x_feof(f)) { return(NULL); } if (maxlen <2) { return(NULL); } if (!s2) { maxlen = MIN(maxlen,8); s = (char *)SMB_MALLOC(maxlen); } if (!s) { return(NULL); } *s = 0; while (len < maxlen-1) { c = x_getc(f); switch (c) { case '\r': break; case '\n': while (len > 0 && s[len-1] == ' ') { s[--len] = 0; } if (len > 0 && s[len-1] == '\\') { s[--len] = 0; start_of_line = True; break; } return(s); case EOF: if (len <= 0 && !s2) { SAFE_FREE(s); } return(len>0?s:NULL); case ' ': if (start_of_line) { break; } default: start_of_line = False; s[len++] = c; s[len] = 0; } if (!s2 && len > maxlen-3) { maxlen *= 2; s = (char *)SMB_REALLOC(s,maxlen); if (!s) { DEBUG(0,("fgets_slash: failed to expand buffer!\n")); return(NULL); } } } return(s); }
bool cli_receive_nt_trans(struct cli_state *cli, char **param, unsigned int *param_len, char **data, unsigned int *data_len) { unsigned int total_data=0; unsigned int total_param=0; unsigned int this_data,this_param; uint8 eclass; uint32 ecode; bool ret = False; uint16_t mid; *data_len = *param_len = 0; mid = SVAL(cli->outbuf,smb_mid); if (!cli_receive_smb(cli)) { cli_state_seqnum_remove(cli, mid); return False; } show_msg(cli->inbuf); /* sanity check */ if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); cli_state_seqnum_remove(cli, mid); return(False); } /* * An NT RPC pipe call can return ERRDOS, ERRmoredata * to a trans call. This is not an error and should not * be treated as such. */ if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if (!(eclass == ERRDOS && ecode == ERRmoredata)) { goto out; } } /* * Likewise for NT_STATUS_BUFFER_TOO_SMALL */ if (cli_is_nt_error(cli)) { if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_BUFFER_TOO_SMALL)) { goto out; } } /* parse out the lengths */ total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount); total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount); /* Only allow 16 megs. */ if (total_param > 16*1024*1024) { DEBUG(0,("cli_receive_nt_trans: param buffer too large %d\n", total_param)); goto out; } if (total_data > 16*1024*1024) { DEBUG(0,("cli_receive_nt_trans: data buffer too large %d\n", total_data)); goto out; } /* allocate it */ if (total_data) { /* We know adding 2 is safe as total_data is less * than 16mb (above). */ *data = (char *)SMB_REALLOC(*data,total_data+2); if (!(*data)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); goto out; } } if (total_param) { /* We know adding 2 is safe as total_param is less * than 16mb (above). */ *param = (char *)SMB_REALLOC(*param,total_param+2); if (!(*param)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); goto out; } } while (1) { this_data = SVAL(cli->inbuf,smb_ntr_DataCount); this_param = SVAL(cli->inbuf,smb_ntr_ParameterCount); if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); goto out; } if (this_data + *data_len < this_data || this_data + *data_len < *data_len || this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); goto out; } if (this_data) { unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); if (data_offset_out > total_data || data_offset_out + this_data > total_data || data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); goto out; } if (data_offset_in > cli->bufsize || data_offset_in + this_data > cli->bufsize || data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); goto out; } memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); } if (this_param) { unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); if (param_offset_out > total_param || param_offset_out + this_param > total_param || param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); goto out; } if (param_offset_in > cli->bufsize || param_offset_in + this_param > cli->bufsize || param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); goto out; } memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); } *data_len += this_data; *param_len += this_param; if (total_data <= *data_len && total_param <= *param_len) { ret = True; break; } if (!cli_receive_smb(cli)) { goto out; } show_msg(cli->inbuf); /* sanity check */ if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); goto out; } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if(!(eclass == ERRDOS && ecode == ERRmoredata)) { goto out; } } /* * Likewise for NT_STATUS_BUFFER_TOO_SMALL */ if (cli_is_nt_error(cli)) { if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_BUFFER_TOO_SMALL)) { goto out; } } /* parse out the total lengths again - they can shrink! */ if (IVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount); if (IVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount); if (total_data <= *data_len && total_param <= *param_len) { ret = True; break; } } out: cli_state_seqnum_remove(cli, mid); if (ret) { /* Ensure the last 2 bytes of param and data are 2 null * bytes. These are malloc'ed, but not included in any * length counts. This allows cli_XX string reading functions * to safely null terminate. */ if (total_data) { SSVAL(*data,total_data,0); } if (total_param) { SSVAL(*param,total_param,0); } } return ret; }
bool cli_receive_trans(struct cli_state *cli,int trans, char **param, unsigned int *param_len, char **data, unsigned int *data_len) { unsigned int total_data=0; unsigned int total_param=0; unsigned int this_data,this_param; NTSTATUS status; bool ret = False; uint16_t mid; *data_len = *param_len = 0; mid = SVAL(cli->outbuf,smb_mid); if (!cli_receive_smb(cli)) { cli_state_seqnum_remove(cli, mid); return False; } show_msg(cli->inbuf); /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); cli_state_seqnum_remove(cli, mid); return False; } /* * An NT RPC pipe call can return ERRDOS, ERRmoredata * to a trans call. This is not an error and should not * be treated as such. Note that STATUS_NO_MORE_FILES is * returned when a trans2 findfirst/next finishes. * When setting up an encrypted transport we can also * see NT_STATUS_MORE_PROCESSING_REQUIRED here. * * Vista returns NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT if the folder * "<share>/Users/All Users" is enumerated. This is a special pseudo * folder, and the response does not have parameters (nor a parameter * length). */ status = cli_nt_error(cli); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES) || NT_STATUS_EQUAL(status,NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) { goto out; } } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); total_param = SVAL(cli->inbuf,smb_tprcnt); /* allocate it */ if (total_data!=0) { /* We know adding 2 is safe as total_data is an * SVAL <= 0xFFFF. */ *data = (char *)SMB_REALLOC(*data,total_data+2); if (!(*data)) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); goto out; } } if (total_param!=0) { /* We know adding 2 is safe as total_param is an * SVAL <= 0xFFFF. */ *param = (char *)SMB_REALLOC(*param,total_param+2); if (!(*param)) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); goto out; } } for (;;) { this_data = SVAL(cli->inbuf,smb_drcnt); this_param = SVAL(cli->inbuf,smb_prcnt); if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_trans\n")); goto out; } if (this_data + *data_len < this_data || this_data + *data_len < *data_len || this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_trans\n")); goto out; } if (this_data) { unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); if (data_offset_out > total_data || data_offset_out + this_data > total_data || data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); goto out; } if (data_offset_in > cli->bufsize || data_offset_in + this_data > cli->bufsize || data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); goto out; } memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); } if (this_param) { unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); if (param_offset_out > total_param || param_offset_out + this_param > total_param || param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); goto out; } if (param_offset_in > cli->bufsize || param_offset_in + this_param > cli->bufsize || param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); goto out; } memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); } *data_len += this_data; *param_len += this_param; if (total_data <= *data_len && total_param <= *param_len) { ret = True; break; } if (!cli_receive_smb(cli)) { goto out; } show_msg(cli->inbuf); /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); goto out; } if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { goto out; } } /* parse out the total lengths again - they can shrink! */ if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) total_data = SVAL(cli->inbuf,smb_tdrcnt); if (SVAL(cli->inbuf,smb_tprcnt) < total_param) total_param = SVAL(cli->inbuf,smb_tprcnt); if (total_data <= *data_len && total_param <= *param_len) { ret = True; break; } } out: cli_state_seqnum_remove(cli, mid); if (ret) { /* Ensure the last 2 bytes of param and data are 2 null * bytes. These are malloc'ed, but not included in any * length counts. This allows cli_XX string reading functions * to safely null terminate. */ if (total_data) { SSVAL(*data,total_data,0); } if (total_param) { SSVAL(*param,total_param,0); } } return ret; }
BOOL smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string) { UNISTR chaine; prs_struct *ps=&buffer->prs; if (MARSHALLING(ps)) { uint32 struct_offset = prs_offset(ps); uint32 relative_offset; uint16 *p; uint16 *q; uint16 zero=0; p=*string; q=*string; /* first write the last 0 */ buffer->string_at_end -= 2; if(!prs_set_offset(ps, buffer->string_at_end)) return False; if(!prs_uint16("leading zero", ps, depth, &zero)) return False; while (p && (*p!=0)) { while (*q!=0) q++; /* Yes this should be malloc not talloc. Don't change. */ chaine.buffer = (uint16 *) SMB_MALLOC((q-p+1)*sizeof(uint16)); if (chaine.buffer == NULL) return False; memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); buffer->string_at_end -= (q-p+1)*sizeof(uint16); if(!prs_set_offset(ps, buffer->string_at_end)) { SAFE_FREE(chaine.buffer); return False; } /* write the string */ if (!smb_io_unistr(desc, &chaine, ps, depth)) { SAFE_FREE(chaine.buffer); return False; } q++; p=q; SAFE_FREE(chaine.buffer); } if(!prs_set_offset(ps, struct_offset)) return False; relative_offset=buffer->string_at_end - buffer->struct_start; /* write its offset */ if (!prs_uint32("offset", ps, depth, &relative_offset)) return False; } else { /* UNMARSHALLING */ uint32 old_offset; uint16 *chaine2=NULL; int l_chaine=0; int l_chaine2=0; size_t realloc_size = 0; *string=NULL; /* read the offset */ if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) return False; old_offset = prs_offset(ps); if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) return False; do { if (!smb_io_unistr(desc, &chaine, ps, depth)) return False; l_chaine=str_len_uni(&chaine); /* we're going to add two more bytes here in case this is the last string in the array and we need to add an extra NULL for termination */ if (l_chaine > 0) { realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16); /* Yes this should be realloc - it's freed below. JRA */ if((chaine2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) { return False; } memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); l_chaine2+=l_chaine+1; } } while(l_chaine!=0); /* the end should be bould NULL terminated so add the second one here */ if (chaine2) { chaine2[l_chaine2] = '\0'; *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size); if (!*string) { return False; } SAFE_FREE(chaine2); } if(!prs_set_offset(ps, old_offset)) return False; } return True; }
SMB_ACL_T aixacl_to_smbacl(struct acl *file_acl) { struct acl_entry *acl_entry; struct ace_id *idp; struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t); struct smb_acl_entry *ace; int i; if (result == NULL) { return NULL; } ZERO_STRUCTP(result); /* Point to the first acl entry in the acl */ acl_entry = file_acl->acl_ext; DEBUG(10,("acl_entry is %p\n",(void *)acl_entry)); DEBUG(10,("acl_last(file_acl) id %p\n",(void *)acl_last(file_acl))); /* Check if the extended acl bit is on. * * If it isn't, do not show the * * contents of the acl since AIX intends * * the extended info to remain unused */ if(file_acl->acl_mode & S_IXACL){ /* while we are not pointing to the very end */ while(acl_entry < acl_last(file_acl)) { /* before we malloc anything, make sure this is */ /* a valid acl entry and one that we want to map */ idp = id_nxt(acl_entry->ace_id); if((acl_entry->ace_type == ACC_SPECIFY || (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) { acl_entry = acl_nxt(acl_entry); continue; } idp = acl_entry->ace_id; DEBUG(10,("idp->id_data is %d\n",idp->id_data[0])); result = SMB_REALLOC(result, sizeof(struct smb_acl_t) + (sizeof(struct smb_acl_entry) * (result->count+1))); if (result == NULL) { DEBUG(0, ("SMB_REALLOC failed\n")); errno = ENOMEM; return NULL; } DEBUG(10,("idp->id_type is %d\n",idp->id_type)); ace = &result->acl[result->count]; ace->a_type = idp->id_type; switch(ace->a_type) { case ACEID_USER: { ace->uid = idp->id_data[0]; DEBUG(10,("case ACEID_USER ace->uid is %d\n",ace->uid)); ace->a_type = SMB_ACL_USER; break; } case ACEID_GROUP: { ace->gid = idp->id_data[0]; DEBUG(10,("case ACEID_GROUP ace->gid is %d\n",ace->gid)); ace->a_type = SMB_ACL_GROUP; break; } default: break; } /* The access in the acl entries must be left shifted by * * three bites, because they will ultimately be compared * * to S_IRUSR, S_IWUSR, and S_IXUSR. */ switch(acl_entry->ace_type){ case ACC_PERMIT: case ACC_SPECIFY: ace->a_perm = acl_entry->ace_access; ace->a_perm <<= 6; DEBUG(10,("ace->a_perm is %d\n",ace->a_perm)); break; case ACC_DENY: /* Since there is no way to return a DENY acl entry * * change to PERMIT and then shift. */ DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access)); ace->a_perm = ~acl_entry->ace_access & 7; DEBUG(10,("ace->a_perm is %d\n",ace->a_perm)); ace->a_perm <<= 6; break; default: DEBUG(0, ("unknown ace->type\n")); SAFE_FREE(result); return(0); } result->count++; ace->a_perm |= (ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0; ace->a_perm |= (ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0; ace->a_perm |= (ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0; DEBUG(10,("ace->a_perm is %d\n",ace->a_perm)); DEBUG(10,("acl_entry = %p\n",(void *)acl_entry)); DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type)); acl_entry = acl_nxt(acl_entry); } } /* end of if enabled */ /* Since owner, group, other acl entries are not * * part of the acl entries in an acl, they must * * be dummied up to become part of the list. */ for( i = 1; i < 4; i++) { DEBUG(10,("i is %d\n",i)); result = SMB_REALLOC(result, sizeof(struct smb_acl_t) + (sizeof(struct smb_acl_entry) * (result->count+1))); if (result == NULL) { DEBUG(0, ("SMB_REALLOC failed\n")); errno = ENOMEM; DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno)); return NULL; } ace = &result->acl[result->count]; ace->uid = 0; ace->gid = 0; DEBUG(10,("ace->uid = %d\n",ace->uid)); switch(i) { case 2: ace->a_perm = file_acl->g_access << 6; ace->a_type = SMB_ACL_GROUP_OBJ; break; case 3: ace->a_perm = file_acl->o_access << 6; ace->a_type = SMB_ACL_OTHER; break; case 1: ace->a_perm = file_acl->u_access << 6; ace->a_type = SMB_ACL_USER_OBJ; break; default: return(NULL); } ace->a_perm |= ((ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0); ace->a_perm |= ((ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0); ace->a_perm |= ((ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0); memcpy(&result->acl[result->count],ace,sizeof(struct smb_acl_entry)); result->count++; DEBUG(10,("ace->a_perm = %d\n",ace->a_perm)); DEBUG(10,("ace->a_type = %d\n",ace->a_type)); } return result; }
static BOOL regdb_store_keys_internal( const char *key, REGSUBKEY_CTR *ctr ) { TDB_DATA kbuf, dbuf; char *buffer; int i = 0; uint32 len, buflen; BOOL ret = True; uint32 num_subkeys = regsubkey_ctr_numkeys( ctr ); pstring keyname; if ( !key ) return False; pstrcpy( keyname, key ); normalize_reg_path( keyname ); /* allocate some initial memory */ if (!(buffer = (char *)SMB_MALLOC(sizeof(pstring)))) { return False; } buflen = sizeof(pstring); len = 0; /* store the number of subkeys */ len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys ); /* pack all the strings */ for (i=0; i<num_subkeys; i++) { len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) ); if ( len > buflen ) { /* allocate some extra space */ if ((buffer = (char *)SMB_REALLOC( buffer, len*2 )) == NULL) { DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2)); ret = False; goto done; } buflen = len*2; len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) ); } } /* finally write out the data */ kbuf.dptr = keyname; kbuf.dsize = strlen(keyname)+1; dbuf.dptr = buffer; dbuf.dsize = len; if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) { ret = False; goto done; } done: SAFE_FREE( buffer ); return ret; }