2023-08-07 07:43:48 +03:00
/*
2003-04-12 03:32:00 +04:00
Unix SMB / CIFS implementation .
QUOTA get / set utility
2011-01-15 18:07:31 +03:00
2003-04-12 03:32:00 +04:00
Copyright ( C ) Andrew Tridgell 2000
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Jeremy Allison 2000
Copyright ( C ) Stefan ( metze ) Metzmacher 2003
2011-01-15 18:07:31 +03:00
2003-04-12 03:32:00 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-04-12 03:32:00 +04:00
( at your option ) any later version .
2011-01-15 18:07:31 +03:00
2003-04-12 03:32:00 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2011-01-15 18:07:31 +03:00
2003-04-12 03:32:00 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-04-12 03:32:00 +04:00
*/
# include "includes.h"
2021-01-13 16:38:17 +03:00
# include "lib/cmdline/cmdline.h"
2011-02-28 12:19:44 +03:00
# include "rpc_client/cli_pipe.h"
2010-05-05 03:39:16 +04:00
# include "../librpc/gen_ndr/ndr_lsa.h"
2010-05-18 20:26:16 +04:00
# include "rpc_client/cli_lsarpc.h"
2010-08-18 18:44:47 +04:00
# include "fake_file.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2023-08-07 07:43:06 +03:00
# include "lib/param/param.h"
2003-04-12 03:32:00 +04:00
2007-12-04 05:48:41 +03:00
static char * server ;
2003-04-12 03:32:00 +04:00
/* numeric is set when the user wants numeric SIDs and ACEs rather
than going via LSA calls to resolve them */
2007-10-19 04:40:25 +04:00
static bool numeric ;
static bool verbose ;
2003-04-12 03:32:00 +04:00
enum todo_values { NOOP_QUOTA = 0 , FS_QUOTA , USER_QUOTA , LIST_QUOTA , SET_QUOTA } ;
enum exit_values { EXIT_OK , EXIT_FAILED , EXIT_PARSE_ERROR } ;
2005-09-30 21:13:37 +04:00
static struct cli_state * cli_ipc ;
static struct rpc_pipe_client * global_pipe_hnd ;
2009-03-19 00:49:41 +03:00
static struct policy_handle pol ;
2007-10-19 04:40:25 +04:00
static bool got_policy_hnd ;
2003-04-12 03:32:00 +04:00
static struct cli_state * connect_one ( const char * share ) ;
/* Open cli connection and policy handle */
2007-10-19 04:40:25 +04:00
static bool cli_open_policy_hnd ( void )
2003-04-12 03:32:00 +04:00
{
/* Initialise cli LSA connection */
if ( ! cli_ipc ) {
2005-09-30 21:13:37 +04:00
NTSTATUS ret ;
2003-04-12 03:32:00 +04:00
cli_ipc = connect_one ( " IPC$ " ) ;
2008-07-20 13:04:31 +04:00
ret = cli_rpc_pipe_open_noauth ( cli_ipc ,
2013-05-24 15:29:28 +04:00
& ndr_table_lsarpc ,
2008-07-20 13:04:31 +04:00
& global_pipe_hnd ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-04-12 03:32:00 +04:00
return False ;
}
}
2007-12-04 05:48:41 +03:00
2003-04-12 03:32:00 +04:00
/* Open policy handle */
if ( ! got_policy_hnd ) {
2009-04-15 03:12:13 +04:00
/* Some systems don't support SEC_FLAG_MAXIMUM_ALLOWED,
2003-04-12 03:32:00 +04:00
but NT sends 0x2000000 so we might as well do it too . */
2023-08-07 07:43:48 +03:00
if ( ! NT_STATUS_IS_OK ( rpccli_lsa_open_policy ( global_pipe_hnd , talloc_tos ( ) , True ,
2003-04-12 03:32:00 +04:00
GENERIC_EXECUTE_ACCESS , & pol ) ) ) {
return False ;
}
got_policy_hnd = True ;
}
2011-01-15 18:07:31 +03:00
2003-04-12 03:32:00 +04:00
return True ;
}
/* convert a SID to a string, either numeric or username/group */
2010-05-21 05:25:01 +04:00
static void SidToString ( fstring str , struct dom_sid * sid , bool _numeric )
2003-04-12 03:32:00 +04:00
{
char * * domains = NULL ;
char * * names = NULL ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types = NULL ;
2003-04-12 03:32:00 +04:00
2007-12-16 00:47:30 +03:00
sid_to_fstring ( str , sid ) ;
2003-04-12 03:32:00 +04:00
if ( _numeric ) return ;
/* Ask LSA to convert the sid to a name */
if ( ! cli_open_policy_hnd ( ) | |
2007-11-30 00:24:54 +03:00
! NT_STATUS_IS_OK ( rpccli_lsa_lookup_sids ( global_pipe_hnd , talloc_tos ( ) ,
2023-08-07 07:43:48 +03:00
& pol , 1 , sid , & domains ,
2003-04-12 03:32:00 +04:00
& names , & types ) ) | |
! domains | | ! domains [ 0 ] | | ! names | | ! names [ 0 ] ) {
return ;
}
/* Converted OK */
slprintf ( str , sizeof ( fstring ) - 1 , " %s%s%s " ,
domains [ 0 ] , lp_winbind_separator ( ) ,
names [ 0 ] ) ;
}
/* convert a string to a SID, either numeric or username/group */
2010-05-21 05:25:01 +04:00
static bool StringToSid ( struct dom_sid * sid , const char * str )
2003-04-12 03:32:00 +04:00
{
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types = NULL ;
2010-05-21 05:25:01 +04:00
struct dom_sid * sids = NULL ;
2007-10-19 04:40:25 +04:00
bool result = True ;
2003-04-12 03:32:00 +04:00
2010-11-14 17:15:52 +03:00
if ( string_to_sid ( sid , str ) ) {
return true ;
2003-04-12 03:32:00 +04:00
}
if ( ! cli_open_policy_hnd ( ) | |
2007-11-30 00:24:54 +03:00
! NT_STATUS_IS_OK ( rpccli_lsa_lookup_names ( global_pipe_hnd , talloc_tos ( ) ,
2023-08-07 07:43:48 +03:00
& pol , 1 , & str , NULL , 1 , & sids ,
2003-04-12 03:32:00 +04:00
& types ) ) ) {
result = False ;
goto done ;
}
sid_copy ( sid , & sids [ 0 ] ) ;
done :
return result ;
}
# define QUOTA_GET 1
# define QUOTA_SETLIM 2
# define QUOTA_SETFLAGS 3
# define QUOTA_LIST 4
enum { PARSE_FLAGS , PARSE_LIM } ;
2007-12-04 05:48:41 +03:00
static int parse_quota_set ( TALLOC_CTX * ctx ,
char * set_str ,
char * * pp_username_str ,
enum SMB_QUOTA_TYPE * qtype ,
int * cmd ,
SMB_NTQUOTA_STRUCT * pqt )
2003-04-12 03:32:00 +04:00
{
char * p = set_str , * p2 ;
int todo ;
2007-10-19 04:40:25 +04:00
bool stop = False ;
bool enable = False ;
bool deny = False ;
2007-12-04 05:48:41 +03:00
* pp_username_str = NULL ;
2003-10-23 03:38:20 +04:00
if ( strnequal ( set_str , " UQLIM: " , 6 ) ) {
2003-04-12 03:32:00 +04:00
p + = 6 ;
* qtype = SMB_USER_QUOTA_TYPE ;
* cmd = QUOTA_SETLIM ;
todo = PARSE_LIM ;
if ( ( p2 = strstr ( p , " : " ) ) = = NULL ) {
return - 1 ;
}
2007-12-04 05:48:41 +03:00
2003-04-12 03:32:00 +04:00
* p2 = ' \0 ' ;
p2 + + ;
2007-12-04 05:48:41 +03:00
* pp_username_str = talloc_strdup ( ctx , p ) ;
2003-04-12 03:32:00 +04:00
p = p2 ;
2003-10-23 03:38:20 +04:00
} else if ( strnequal ( set_str , " FSQLIM: " , 7 ) ) {
2003-04-12 03:32:00 +04:00
p + = 7 ;
* qtype = SMB_USER_FS_QUOTA_TYPE ;
* cmd = QUOTA_SETLIM ;
todo = PARSE_LIM ;
2003-10-23 03:38:20 +04:00
} else if ( strnequal ( set_str , " FSQFLAGS: " , 9 ) ) {
2003-04-12 03:32:00 +04:00
p + = 9 ;
todo = PARSE_FLAGS ;
* qtype = SMB_USER_FS_QUOTA_TYPE ;
* cmd = QUOTA_SETFLAGS ;
} else {
return - 1 ;
}
switch ( todo ) {
case PARSE_LIM :
2013-04-16 14:39:55 +04:00
if ( sscanf ( p , " % " SCNu64 " /% " SCNu64 , & pqt - > softlim ,
& pqt - > hardlim ) ! = 2 )
{
2003-04-12 03:32:00 +04:00
return - 1 ;
}
2007-12-04 05:48:41 +03:00
2003-04-12 03:32:00 +04:00
break ;
case PARSE_FLAGS :
while ( ! stop ) {
if ( ( p2 = strstr ( p , " / " ) ) = = NULL ) {
stop = True ;
} else {
* p2 = ' \0 ' ;
p2 + + ;
}
2003-10-23 03:38:20 +04:00
if ( strnequal ( p , " QUOTA_ENABLED " , 13 ) ) {
2003-04-12 03:32:00 +04:00
enable = True ;
2003-10-23 03:38:20 +04:00
} else if ( strnequal ( p , " DENY_DISK " , 9 ) ) {
2003-04-12 03:32:00 +04:00
deny = True ;
2003-10-23 03:38:20 +04:00
} else if ( strnequal ( p , " LOG_SOFTLIMIT " , 13 ) ) {
2003-04-12 03:32:00 +04:00
pqt - > qflags | = QUOTAS_LOG_THRESHOLD ;
2003-10-23 03:38:20 +04:00
} else if ( strnequal ( p , " LOG_HARDLIMIT " , 13 ) ) {
2003-04-12 03:32:00 +04:00
pqt - > qflags | = QUOTAS_LOG_LIMIT ;
} else {
return - 1 ;
}
p = p2 ;
}
if ( deny ) {
pqt - > qflags | = QUOTAS_DENY_DISK ;
} else if ( enable ) {
pqt - > qflags | = QUOTAS_ENABLED ;
}
2007-12-04 05:48:41 +03:00
break ;
2003-04-12 03:32:00 +04:00
}
return 0 ;
}
2011-01-16 14:26:45 +03:00
static const char * quota_str_static ( uint64_t val , bool special , bool _numeric )
{
const char * result ;
2016-03-30 14:20:44 +03:00
if ( ! _numeric & & special & & val = = 0 ) {
2011-01-16 14:26:45 +03:00
return " NO LIMIT " ;
}
result = talloc_asprintf ( talloc_tos ( ) , " % " PRIu64 , val ) ;
SMB_ASSERT ( result ! = NULL ) ;
return result ;
}
static void dump_ntquota ( SMB_NTQUOTA_STRUCT * qt , bool _verbose ,
bool _numeric ,
void ( * _sidtostring ) ( fstring str ,
struct dom_sid * sid ,
bool _numeric ) )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
if ( ! qt ) {
smb_panic ( " dump_ntquota() called with NULL pointer " ) ;
}
switch ( qt - > qtype ) {
case SMB_USER_FS_QUOTA_TYPE :
{
d_printf ( " File System QUOTAS: \n " ) ;
d_printf ( " Limits: \n " ) ;
d_printf ( " Default Soft Limit: %15s \n " ,
quota_str_static ( qt - > softlim , True , _numeric ) ) ;
d_printf ( " Default Hard Limit: %15s \n " ,
quota_str_static ( qt - > hardlim , True , _numeric ) ) ;
d_printf ( " Quota Flags: \n " ) ;
d_printf ( " Quotas Enabled: %s \n " ,
( ( qt - > qflags & QUOTAS_ENABLED )
| | ( qt - > qflags & QUOTAS_DENY_DISK ) ) ? " On " : " Off " ) ;
d_printf ( " Deny Disk: %s \n " ,
( qt - > qflags & QUOTAS_DENY_DISK ) ? " On " : " Off " ) ;
d_printf ( " Log Soft Limit: %s \n " ,
( qt - > qflags & QUOTAS_LOG_THRESHOLD ) ? " On " : " Off " ) ;
d_printf ( " Log Hard Limit: %s \n " ,
( qt - > qflags & QUOTAS_LOG_LIMIT ) ? " On " : " Off " ) ;
}
break ;
case SMB_USER_QUOTA_TYPE :
{
fstring username_str = { 0 } ;
if ( _sidtostring ) {
_sidtostring ( username_str , & qt - > sid , _numeric ) ;
} else {
sid_to_fstring ( username_str , & qt - > sid ) ;
}
if ( _verbose ) {
d_printf ( " Quotas for User: %s \n " , username_str ) ;
d_printf ( " Used Space: %15s \n " ,
quota_str_static ( qt - > usedspace , False ,
_numeric ) ) ;
d_printf ( " Soft Limit: %15s \n " ,
quota_str_static ( qt - > softlim , True ,
_numeric ) ) ;
d_printf ( " Hard Limit: %15s \n " ,
quota_str_static ( qt - > hardlim , True , _numeric ) ) ;
} else {
d_printf ( " %-30s: " , username_str ) ;
d_printf ( " %15s/ " , quota_str_static (
qt - > usedspace , False , _numeric ) ) ;
d_printf ( " %15s/ " , quota_str_static (
qt - > softlim , True , _numeric ) ) ;
d_printf ( " %15s \n " , quota_str_static (
qt - > hardlim , True , _numeric ) ) ;
}
}
break ;
default :
d_printf ( " dump_ntquota() invalid qtype(%d) \n " , qt - > qtype ) ;
}
TALLOC_FREE ( frame ) ;
return ;
}
static void dump_ntquota_list ( SMB_NTQUOTA_LIST * * qtl , bool _verbose ,
bool _numeric ,
void ( * _sidtostring ) ( fstring str ,
struct dom_sid * sid ,
bool _numeric ) )
{
SMB_NTQUOTA_LIST * cur ;
for ( cur = * qtl ; cur ; cur = cur - > next ) {
if ( cur - > quotas )
dump_ntquota ( cur - > quotas , _verbose , _numeric ,
_sidtostring ) ;
}
}
2007-12-04 05:48:41 +03:00
static int do_quota ( struct cli_state * cli ,
enum SMB_QUOTA_TYPE qtype ,
2015-05-01 05:22:21 +03:00
uint16_t cmd ,
2007-12-04 05:48:41 +03:00
const char * username_str ,
SMB_NTQUOTA_STRUCT * pqt )
2003-04-12 03:32:00 +04:00
{
2015-05-01 05:22:21 +03:00
uint32_t fs_attrs = 0 ;
2009-05-01 02:26:43 +04:00
uint16_t quota_fnum = 0 ;
2003-04-12 03:32:00 +04:00
SMB_NTQUOTA_LIST * qtl = NULL ;
2016-09-21 18:37:40 +03:00
TALLOC_CTX * qtl_ctx = NULL ;
2003-04-12 03:32:00 +04:00
SMB_NTQUOTA_STRUCT qt ;
2010-11-14 16:11:24 +03:00
NTSTATUS status ;
2003-04-12 03:32:00 +04:00
ZERO_STRUCT ( qt ) ;
2010-11-14 16:11:24 +03:00
status = cli_get_fs_attr_info ( cli , & fs_attrs ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " Failed to get the filesystem attributes %s. \n " ,
2010-11-14 16:11:24 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
if ( ! ( fs_attrs & FILE_VOLUME_QUOTAS ) ) {
d_printf ( " Quotas are not supported by the server. \n " ) ;
2007-12-04 05:48:41 +03:00
return 0 ;
2003-04-12 03:32:00 +04:00
}
2010-11-14 16:11:24 +03:00
status = cli_get_quota_handle ( cli , & quota_fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-09-17 19:09:20 +04:00
d_printf ( " Quotas are not enabled on this share. \n " ) ;
d_printf ( " Failed to open %s %s. \n " ,
2010-11-14 16:11:24 +03:00
FAKE_FILE_NAME_QUOTA_WIN32 ,
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
switch ( qtype ) {
case SMB_USER_QUOTA_TYPE :
if ( ! StringToSid ( & qt . sid , username_str ) ) {
d_printf ( " StringToSid() failed for [%s] \n " , username_str ) ;
return - 1 ;
}
2007-12-04 05:48:41 +03:00
2003-04-12 03:32:00 +04:00
switch ( cmd ) {
case QUOTA_GET :
2011-01-16 10:34:58 +03:00
status = cli_get_user_quota (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_get_user_quota %s \n " ,
2011-01-16 10:34:58 +03:00
nt_errstr ( status ) ,
username_str ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
dump_ntquota ( & qt , verbose , numeric , SidToString ) ;
break ;
case QUOTA_SETLIM :
pqt - > sid = qt . sid ;
2016-09-21 18:37:40 +03:00
if ( ( qtl_ctx = talloc_init (
" SMB_USER_QUOTA_SET " ) ) = =
NULL ) {
return - 1 ;
}
if ( ! add_record_to_ntquota_list (
qtl_ctx , pqt , & qtl ) ) {
TALLOC_FREE ( qtl_ctx ) ;
return - 1 ;
}
2011-01-16 13:33:35 +03:00
status = cli_set_user_quota (
2016-09-21 18:37:40 +03:00
cli , quota_fnum , qtl ) ;
free_ntquota_list ( & qtl ) ;
2011-01-16 13:33:35 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_set_user_quota %s \n " ,
2011-01-16 13:33:35 +03:00
nt_errstr ( status ) ,
username_str ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
2011-01-16 10:34:58 +03:00
status = cli_get_user_quota (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_get_user_quota %s \n " ,
2011-01-16 10:34:58 +03:00
nt_errstr ( status ) ,
username_str ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
dump_ntquota ( & qt , verbose , numeric , SidToString ) ;
break ;
case QUOTA_LIST :
2011-01-16 13:53:03 +03:00
status = cli_list_user_quota (
cli , quota_fnum , & qtl ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-09-16 22:01:46 +03:00
d_printf (
" %s cli_list_user_quota \n " ,
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
dump_ntquota_list ( & qtl , verbose , numeric , SidToString ) ;
2007-12-04 05:48:41 +03:00
free_ntquota_list ( & qtl ) ;
2003-04-12 03:32:00 +04:00
break ;
default :
d_printf ( " Unknown Error \n " ) ;
return - 1 ;
2007-12-04 05:48:41 +03:00
}
2003-04-12 03:32:00 +04:00
break ;
case SMB_USER_FS_QUOTA_TYPE :
switch ( cmd ) {
case QUOTA_GET :
2011-01-16 14:03:07 +03:00
status = cli_get_fs_quota_info (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_get_fs_quota_info \n " ,
2011-01-16 14:03:07 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
dump_ntquota ( & qt , True , numeric , NULL ) ;
break ;
case QUOTA_SETLIM :
2011-01-16 14:03:07 +03:00
status = cli_get_fs_quota_info (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_get_fs_quota_info \n " ,
2011-01-16 14:03:07 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
qt . softlim = pqt - > softlim ;
qt . hardlim = pqt - > hardlim ;
2011-01-16 14:14:26 +03:00
status = cli_set_fs_quota_info (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_set_fs_quota_info \n " ,
2011-01-16 14:14:26 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
2011-01-16 14:03:07 +03:00
status = cli_get_fs_quota_info (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_get_fs_quota_info \n " ,
2011-01-16 14:03:07 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
dump_ntquota ( & qt , True , numeric , NULL ) ;
break ;
case QUOTA_SETFLAGS :
2011-01-16 14:03:07 +03:00
status = cli_get_fs_quota_info (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_get_fs_quota_info \n " ,
2011-01-16 14:03:07 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
qt . qflags = pqt - > qflags ;
2011-01-16 14:14:26 +03:00
status = cli_set_fs_quota_info (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_set_fs_quota_info \n " ,
2011-01-16 14:14:26 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
2011-01-16 14:03:07 +03:00
status = cli_get_fs_quota_info (
cli , quota_fnum , & qt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-04-12 03:32:00 +04:00
d_printf ( " %s cli_get_fs_quota_info \n " ,
2011-01-16 14:03:07 +03:00
nt_errstr ( status ) ) ;
2003-04-12 03:32:00 +04:00
return - 1 ;
}
dump_ntquota ( & qt , True , numeric , NULL ) ;
break ;
default :
d_printf ( " Unknown Error \n " ) ;
return - 1 ;
2007-12-04 05:48:41 +03:00
}
2003-04-12 03:32:00 +04:00
break ;
default :
d_printf ( " Unknown Error \n " ) ;
return - 1 ;
}
cli_close ( cli , quota_fnum ) ;
return 0 ;
}
2007-10-25 01:16:54 +04:00
/*****************************************************
Return a connection to a server .
2003-04-12 03:32:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-25 01:16:54 +04:00
2003-04-12 03:32:00 +04:00
static struct cli_state * connect_one ( const char * share )
{
struct cli_state * c ;
NTSTATUS nt_status ;
2008-05-05 18:58:24 +04:00
uint32_t flags = 0 ;
2023-11-23 17:07:53 +03:00
nt_status = cli_full_connection_creds ( talloc_tos ( ) ,
& c ,
lp_netbios_name ( ) ,
server ,
NULL ,
0 ,
share ,
" ????? " ,
samba_cmdline_get_creds ( ) ,
flags ) ;
2008-01-05 11:50:03 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2003-04-12 03:32:00 +04:00
DEBUG ( 0 , ( " cli_full_connection failed! (%s) \n " , nt_errstr ( nt_status ) ) ) ;
return NULL ;
}
2008-01-05 11:50:03 +03:00
return c ;
2003-04-12 03:32:00 +04:00
}
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-02-26 23:16:26 +04:00
int main ( int argc , char * argv [ ] )
2003-04-12 03:32:00 +04:00
{
2014-02-26 23:16:26 +04:00
const char * * argv_const = discard_const_p ( const char * , argv ) ;
2003-04-12 03:32:00 +04:00
char * share ;
int opt ;
int result ;
int todo = 0 ;
2007-12-04 05:48:41 +03:00
char * username_str = NULL ;
char * path = NULL ;
char * set_str = NULL ;
2005-12-03 09:58:54 +03:00
enum SMB_QUOTA_TYPE qtype = SMB_INVALID_QUOTA_TYPE ;
2003-04-12 03:32:00 +04:00
int cmd = 0 ;
2007-10-19 04:40:25 +04:00
static bool test_args = False ;
2003-04-12 03:32:00 +04:00
struct cli_state * cli ;
2007-10-19 04:40:25 +04:00
bool fix_user = False ;
2003-04-12 03:32:00 +04:00
SMB_NTQUOTA_STRUCT qt ;
2007-09-04 09:39:06 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-04-12 03:32:00 +04:00
poptContext pc ;
2021-01-13 16:38:17 +03:00
struct cli_credentials * creds = NULL ;
bool ok ;
2023-08-07 07:43:06 +03:00
struct loadparm_context * lp_ctx = NULL ;
2021-01-13 16:38:17 +03:00
2003-04-12 03:32:00 +04:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
2019-01-14 12:43:48 +03:00
{
2021-01-13 16:37:27 +03:00
. longName = " quota-user " ,
2019-01-14 12:43:48 +03:00
. shortName = ' u ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' u ' ,
. descrip = " Show quotas for user " ,
. argDescrip = " USER " ,
} ,
{
. longName = " list " ,
. shortName = ' L ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' L ' ,
. descrip = " List user quotas " ,
} ,
{
. longName = " fs " ,
. shortName = ' F ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' F ' ,
. descrip = " Show filesystem quotas " ,
} ,
{
. longName = " set " ,
. shortName = ' S ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' S ' ,
. descrip = " Set acls \n "
" SETSTRING: \n "
" UQLIM:<username>/<softlimit>/<hardlimit> for user quotas \n "
" FSQLIM:<softlimit>/<hardlimit> for filesystem defaults \n "
" FSQFLAGS:QUOTA_ENABLED/DENY_DISK/LOG_SOFTLIMIT/LOG_HARD_LIMIT " ,
. argDescrip = " SETSTRING " ,
} ,
{
. longName = " numeric " ,
. shortName = ' n ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' n ' ,
. descrip = " Don't resolve sids or limits to names " ,
} ,
{
. longName = " verbose " ,
. shortName = ' v ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' v ' ,
. descrip = " be verbose " ,
} ,
{
. longName = " test-args " ,
. shortName = ' t ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' t ' ,
. descrip = " Test arguments "
} ,
{
. longName = " max-protocol " ,
. shortName = ' m ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' m ' ,
. descrip = " Set the max protocol level " ,
. argDescrip = " LEVEL "
} ,
2003-04-12 03:32:00 +04:00
POPT_COMMON_SAMBA
POPT_COMMON_CREDENTIALS
2021-01-13 16:38:17 +03:00
POPT_LEGACY_S3
POPT_COMMON_VERSION
2019-01-14 12:43:48 +03:00
POPT_TABLEEND
2003-04-12 03:32:00 +04:00
} ;
2015-03-21 22:00:06 +03:00
smb_init_locale ( ) ;
2005-12-29 01:48:54 +03:00
2003-04-12 03:32:00 +04:00
ZERO_STRUCT ( qt ) ;
2021-01-13 16:38:17 +03:00
ok = samba_cmdline_init ( frame ,
SAMBA_CMDLINE_CONFIG_CLIENT ,
false /* require_smbconf */ ) ;
if ( ! ok ) {
DBG_ERR ( " Failed to init cmdline parser! \n " ) ;
TALLOC_FREE ( frame ) ;
exit ( 1 ) ;
}
2023-08-07 07:43:06 +03:00
lp_ctx = samba_cmdline_get_lp_ctx ( ) ;
2004-09-15 17:57:33 +04:00
/* set default debug level to 1 regardless of what smb.conf sets */
2023-08-07 07:43:06 +03:00
lpcfg_set_cmdline ( lp_ctx , " log level " , " 1 " ) ;
2003-04-12 03:32:00 +04:00
2004-09-15 17:57:33 +04:00
setlinebuf ( stdout ) ;
2003-04-12 03:32:00 +04:00
2021-01-13 16:38:17 +03:00
pc = samba_popt_get_context ( getprogname ( ) ,
argc ,
argv_const ,
long_options , 0 ) ;
if ( pc = = NULL ) {
DBG_ERR ( " Failed to setup popt context! \n " ) ;
TALLOC_FREE ( frame ) ;
exit ( 1 ) ;
}
2007-12-04 05:48:41 +03:00
2003-04-12 03:32:00 +04:00
poptSetOtherOptionHelp ( pc , " //server1/share1 " ) ;
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
2007-10-19 22:38:36 +04:00
case ' n ' :
numeric = true ;
break ;
case ' v ' :
verbose = true ;
break ;
case ' t ' :
test_args = true ;
break ;
2003-04-12 03:32:00 +04:00
case ' L ' :
if ( todo ! = 0 ) {
d_printf ( " Please specify only one option of <-L|-F|-S|-u> \n " ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
todo = LIST_QUOTA ;
break ;
case ' F ' :
if ( todo ! = 0 ) {
d_printf ( " Please specify only one option of <-L|-F|-S|-u> \n " ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
todo = FS_QUOTA ;
break ;
2007-12-04 05:48:41 +03:00
2003-04-12 03:32:00 +04:00
case ' u ' :
if ( todo ! = 0 ) {
d_printf ( " Please specify only one option of <-L|-F|-S|-u> \n " ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
2007-12-04 05:48:41 +03:00
username_str = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! username_str ) {
exit ( EXIT_PARSE_ERROR ) ;
}
2003-04-12 03:32:00 +04:00
todo = USER_QUOTA ;
fix_user = True ;
break ;
2007-12-04 05:48:41 +03:00
2003-04-12 03:32:00 +04:00
case ' S ' :
if ( todo ! = 0 ) {
d_printf ( " Please specify only one option of <-L|-F|-S|-u> \n " ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
2007-12-04 05:48:41 +03:00
set_str = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! set_str ) {
exit ( EXIT_PARSE_ERROR ) ;
}
2003-04-12 03:32:00 +04:00
todo = SET_QUOTA ;
break ;
2016-09-20 18:51:00 +03:00
case ' m ' :
2023-08-07 07:43:06 +03:00
lpcfg_set_cmdline ( lp_ctx ,
" client max protocol " ,
poptGetOptArg ( pc ) ) ;
2016-09-20 18:51:00 +03:00
break ;
2021-09-10 08:12:21 +03:00
case POPT_ERROR_BADOPT :
fprintf ( stderr , " \n Invalid option %s: %s \n \n " ,
poptBadOption ( pc , 0 ) , poptStrerror ( opt ) ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
2003-04-12 03:32:00 +04:00
}
}
2021-01-13 16:38:17 +03:00
creds = samba_cmdline_get_creds ( ) ;
2003-04-12 03:32:00 +04:00
if ( todo = = 0 )
todo = USER_QUOTA ;
2007-12-04 05:48:41 +03:00
if ( ! fix_user ) {
2021-01-13 16:38:17 +03:00
const char * user = cli_credentials_get_username ( creds ) ;
if ( user = = NULL ) {
exit ( EXIT_PARSE_ERROR ) ;
}
username_str = talloc_strdup ( frame , user ) ;
2007-12-04 05:48:41 +03:00
if ( ! username_str ) {
exit ( EXIT_PARSE_ERROR ) ;
}
}
2003-04-12 03:32:00 +04:00
/* Make connection to server */
2007-12-04 05:48:41 +03:00
if ( ! poptPeekArg ( pc ) ) {
2003-04-12 03:32:00 +04:00
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
2007-12-04 05:48:41 +03:00
path = talloc_strdup ( frame , poptGetArg ( pc ) ) ;
if ( ! path ) {
printf ( " Out of memory \n " ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
2023-01-10 14:25:35 +03:00
if ( strncmp ( path , " \\ \\ " , 2 ) & & strncmp ( path , " // " , 2 ) ) {
printf ( " Invalid argument: %s \n " , path ) ;
return - 1 ;
}
2012-10-30 00:12:14 +04:00
poptFreeContext ( pc ) ;
2021-01-13 16:38:17 +03:00
samba_cmdline_burn ( argc , argv ) ;
2012-10-30 00:12:14 +04:00
2007-12-04 05:48:41 +03:00
string_replace ( path , ' / ' , ' \\ ' ) ;
2003-04-12 03:32:00 +04:00
2007-12-04 05:48:41 +03:00
server = SMB_STRDUP ( path + 2 ) ;
if ( ! server ) {
printf ( " Out of memory \n " ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
2003-04-12 03:32:00 +04:00
share = strchr_m ( server , ' \\ ' ) ;
2019-05-08 18:11:13 +03:00
if ( share = = NULL ) {
printf ( " Invalid argument \n " ) ;
2007-05-19 08:23:04 +04:00
exit ( EXIT_PARSE_ERROR ) ;
2003-04-12 03:32:00 +04:00
}
* share = 0 ;
share + + ;
if ( todo = = SET_QUOTA ) {
2007-12-04 05:48:41 +03:00
if ( parse_quota_set ( talloc_tos ( ) , set_str , & username_str , & qtype , & cmd , & qt ) ) {
2003-04-12 03:32:00 +04:00
printf ( " Invalid argument: -S %s \n " , set_str ) ;
exit ( EXIT_PARSE_ERROR ) ;
}
}
if ( ! test_args ) {
cli = connect_one ( share ) ;
if ( ! cli ) {
exit ( EXIT_FAILED ) ;
}
} else {
exit ( EXIT_OK ) ;
}
/* Perform requested action */
switch ( todo ) {
case FS_QUOTA :
result = do_quota ( cli , SMB_USER_FS_QUOTA_TYPE , QUOTA_GET , username_str , NULL ) ;
break ;
case LIST_QUOTA :
result = do_quota ( cli , SMB_USER_QUOTA_TYPE , QUOTA_LIST , username_str , NULL ) ;
break ;
case USER_QUOTA :
result = do_quota ( cli , SMB_USER_QUOTA_TYPE , QUOTA_GET , username_str , NULL ) ;
break ;
case SET_QUOTA :
result = do_quota ( cli , qtype , cmd , username_str , & qt ) ;
break ;
2023-08-07 07:43:48 +03:00
default :
2003-04-12 03:32:00 +04:00
result = EXIT_FAILED ;
break ;
}
2023-10-24 13:01:58 +03:00
gfree_all ( ) ;
2007-09-04 09:39:06 +04:00
talloc_free ( frame ) ;
2003-04-12 03:32:00 +04:00
return result ;
}