BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) { BOOL ret = False; uint16 setup; char params[2]; char data[112]; char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; unsigned int sid_len; memset(data,'\0',112); if (!cli||!pqt) smb_panic("cli_set_user_quota() called with NULL Pointer!"); setup = NT_TRANSACT_SET_USER_QUOTA; SSVAL(params,0,quota_fnum); sid_len = sid_size(&pqt->sid); SIVAL(data,0,0); SIVAL(data,4,sid_len); SBIG_UINT(data, 8,(SMB_BIG_UINT)0); SBIG_UINT(data,16,pqt->usedspace); SBIG_UINT(data,24,pqt->softlim); SBIG_UINT(data,32,pqt->hardlim); sid_linearize(data+40, sid_len, &pqt->sid); if (!cli_send_nt_trans(cli, NT_TRANSACT_SET_USER_QUOTA, 0, &setup, 1, 0, params, 2, 0, data, 112, 0)) { DEBUG(1,("Failed to send NT_TRANSACT_SET_USER_QUOTA\n")); goto cleanup; } if (!cli_receive_nt_trans(cli, &rparam, &rparam_count, &rdata, &rdata_count)) { DEBUG(1,("NT_TRANSACT_SET_USER_QUOTA failed\n")); goto cleanup; } if (cli_is_error(cli)) { ret = False; goto cleanup; } else { ret = True; } cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); return ret; }
void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag) { t->type = type; t->flags = flag; t->size = sid_size(sid) + 8; t->access_mask = mask; ZERO_STRUCTP(&t->trustee); sid_copy(&t->trustee, sid); }
/* return the binary string representation of a DOM_SID caller must free */ char *sid_binstring(DOM_SID *sid) { char *buf, *s; int len = sid_size(sid); buf = malloc(len); if (!buf) return NULL; sid_linearize(buf, len, sid); s = binary_string(buf, len); free(buf); return s; }
char *sid_binstring_hex(const DOM_SID *sid) { char *buf, *s; int len = sid_size(sid); buf = (char *)SMB_MALLOC(len); if (!buf) return NULL; sid_linearize(buf, len, sid); s = binary_string(buf, len); free(buf); return s; }
BOOL sid_linearize(char *outbuf, size_t len, const DOM_SID *sid) { size_t i; if (len < sid_size(sid)) return False; SCVAL(outbuf,0,sid->sid_rev_num); SCVAL(outbuf,1,sid->num_auths); memcpy(&outbuf[2], sid->id_auth, 6); for(i = 0; i < sid->num_auths; i++) SIVAL(outbuf, 8 + (i*4), sid->sub_auths[i]); return True; }
NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask) { unsigned int i = 0; if (!ctx || !pp_new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; *num += 1; if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0) return NT_STATUS_NO_MEMORY; for (i = 0; i < *num - 1; i ++) sec_ace_copy(&(*pp_new)[i], &old[i]); (*pp_new)[i].type = 0; (*pp_new)[i].flags = 0; (*pp_new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid); (*pp_new)[i].access_mask = mask; sid_copy(&(*pp_new)[i].trustee, sid); return NT_STATUS_OK; }
/* * sd_fixup - Fix up a Windows NT security descriptor for libntfs-3g. * * libntfs-3g validates security descriptors before setting them, but old * versions contain bugs causing it to reject unusual but valid security * descriptors: * * - Versions before 2013.1.13 reject security descriptors ending with an empty * SACL (System Access Control List). This bug can be worked around either by * moving the empty SACL earlier in the security descriptor or by removing the * SACL entirely. The latter work-around is valid because an empty SACL is * equivalent to a "null", or non-existent, SACL. * - Versions up to and including 2013.1.13 reject security descriptors ending * with an empty DACL (Discretionary Access Control List). This is very * similar to the SACL bug and should be fixed in the next release after * 2013.1.13. However, removing the DACL is not a valid workaround because * this changes the meaning of the security descriptor--- an empty DACL allows * no access, whereas a "null" DACL allows all access. * * If the security descriptor was fixed, this function returns an allocated * buffer containing the fixed security descriptor, and its size is updated. * Otherwise (or if no memory is available) the original descriptor is returned. */ static u8 * sd_fixup(const u8 *_desc, size_t *size_p) { u32 owner_offset, group_offset, dacl_offset, sacl_offset; bool owner_valid, group_valid; size_t size = *size_p; const wimlib_SECURITY_DESCRIPTOR_RELATIVE *desc = (const wimlib_SECURITY_DESCRIPTOR_RELATIVE*)_desc; wimlib_SECURITY_DESCRIPTOR_RELATIVE *desc_new; const wimlib_SID *owner, *group, *sid; /* Don't attempt to fix clearly invalid security descriptors. */ if (size < sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE)) return (u8*)_desc; if (le16_to_cpu(desc->control) & wimlib_SE_DACL_PRESENT) dacl_offset = le32_to_cpu(desc->dacl_offset); else dacl_offset = 0; if (le16_to_cpu(desc->control) & wimlib_SE_SACL_PRESENT) sacl_offset = le32_to_cpu(desc->sacl_offset); else sacl_offset = 0; /* Check if the security descriptor will be affected by one of the bugs. * If not, do nothing and return. * * Note: HAVE_NTFS_MNT_RDONLY is defined if libntfs-3g is * version 2013.1.13 or later. */ if (!( #if !defined(HAVE_NTFS_MNT_RDONLY) (sacl_offset != 0 && sacl_offset == size - sizeof(wimlib_ACL)) || #endif (dacl_offset != 0 && dacl_offset == size - sizeof(wimlib_ACL)))) return (u8*)_desc; owner_offset = le32_to_cpu(desc->owner_offset); group_offset = le32_to_cpu(desc->group_offset); owner = (const wimlib_SID*)((const u8*)desc + owner_offset); group = (const wimlib_SID*)((const u8*)desc + group_offset); /* We'll try to move the owner or group SID to the end of the security * descriptor to avoid the bug. This is only possible if at least one * is valid. */ owner_valid = (owner_offset != 0) && (owner_offset % 4 == 0) && (owner_offset <= size - sizeof(SID)) && (owner_offset + sid_size(owner) <= size) && (owner_offset >= sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE)); group_valid = (group_offset != 0) && (group_offset % 4 == 0) && (group_offset <= size - sizeof(SID)) && (group_offset + sid_size(group) <= size) && (group_offset >= sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE)); if (owner_valid) { sid = owner; } else if (group_valid) { sid = group; } else { return (u8*)_desc; } desc_new = MALLOC(size + sid_size(sid)); if (!desc_new) return (u8*)_desc; memcpy(desc_new, desc, size); if (owner_valid) desc_new->owner_offset = cpu_to_le32(size); else if (group_valid) desc_new->group_offset = cpu_to_le32(size); memcpy((u8*)desc_new + size, sid, sid_size(sid)); *size_p = size + sid_size(sid); return (u8*)desc_new; }
BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) { BOOL ret = False; uint16 setup; char params[16]; unsigned int data_len; char data[SID_MAX_SIZE+8]; char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; unsigned int sid_len; unsigned int offset; if (!cli||!pqt) smb_panic("cli_get_user_quota() called with NULL Pointer!"); setup = NT_TRANSACT_GET_USER_QUOTA; SSVAL(params, 0,quota_fnum); SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID); SIVAL(params, 4,0x00000024); SIVAL(params, 8,0x00000000); SIVAL(params,12,0x00000024); sid_len = sid_size(&pqt->sid); data_len = sid_len+8; SIVAL(data, 0, 0x00000000); SIVAL(data, 4, sid_len); sid_linearize(data+8, sid_len, &pqt->sid); if (!cli_send_nt_trans(cli, NT_TRANSACT_GET_USER_QUOTA, 0, &setup, 1, 0, params, 16, 4, data, data_len, 112)) { DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); goto cleanup; } if (!cli_receive_nt_trans(cli, &rparam, &rparam_count, &rdata, &rdata_count)) { DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); goto cleanup; } if (cli_is_error(cli)) { ret = False; goto cleanup; } else { ret = True; } if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) { ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt); } else { DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n")); ret = False; } cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); return ret; }