diff options
| -rw-r--r-- | source3/Makefile.in | 24 | ||||
| -rw-r--r-- | source3/include/fake_file.h | 46 | ||||
| -rw-r--r-- | source3/include/ntquotas.h | 97 | ||||
| -rw-r--r-- | source3/include/smb.h | 71 | ||||
| -rw-r--r-- | source3/include/trans2.h | 6 | ||||
| -rw-r--r-- | source3/lib/util_str.c | 6 | ||||
| -rw-r--r-- | source3/libsmb/clifile.c | 17 | ||||
| -rw-r--r-- | source3/libsmb/clifsinfo.c | 76 | ||||
| -rw-r--r-- | source3/libsmb/cliquota.c | 633 | ||||
| -rw-r--r-- | source3/python/py_smb.c | 4 | ||||
| -rw-r--r-- | source3/torture/nbio.c | 4 | ||||
| -rw-r--r-- | source3/torture/torture.c | 157 | ||||
| -rw-r--r-- | source3/torture/utable.c | 4 | ||||
| -rw-r--r-- | source3/utils/smbcquotas.c | 545 | 
14 files changed, 1562 insertions, 128 deletions
| diff --git a/source3/Makefile.in b/source3/Makefile.in index 641294790d..b7a2519ce7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -127,7 +127,7 @@ BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \  	bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@  BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \  	bin/profiles@EXEEXT@ bin/smbgroupedit@EXEEXT@ bin/ntlm_auth@EXEEXT@ \ -	bin/editreg@EXEEXT@ +	bin/editreg@EXEEXT@ bin/smbcquotas@EXEEXT@  TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \  	bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \ @@ -215,6 +215,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \  	     libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \  	     libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \  	     libsmb/clistr.o libsmb/smb_signing.o \ +	     libsmb/cliquota.o libsmb/clifsinfo.o \               libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \  	     libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \  	     libsmb/passchange.o libsmb/doserr.o \ @@ -532,6 +533,11 @@ SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \  			   $(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \  			   $(POPT_LIB_OBJ) +SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +		$(PARAM_OBJ) \ +		$(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \ +		$(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) +  TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ)  RPCTORTURE_OBJ = torture/rpctorture.o \ @@ -640,6 +646,8 @@ locktest : SHOWFLAGS bin/locktest@EXEEXT@  smbcacls : SHOWFLAGS bin/smbcacls@EXEEXT@ +smbcquotas : SHOWFLAGS bin/smbcquotas@EXEEXT@ +  locktest2 : SHOWFLAGS bin/locktest2@EXEEXT@  rpctorture : SHOWFLAGS bin/rpctorture@EXEEXT@ @@ -840,6 +848,10 @@ bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy  	@echo Linking $@  	@$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) +bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy +	@echo Linking $@ +	@$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) +  bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy  	@echo Linking $@  	@$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) @@ -888,16 +900,16 @@ bin/smbwrapper.32.@SHLIBEXT@: $(PICOBJS32)  bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS)  	@echo Linking libsmbclient shared library $@ -	$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \ +	@$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \  	$(KRB5LIBS) @SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR)  bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS)  	@echo Linking libsmbclient non-shared library $@ -	-$(AR) -rc $@ $(LIBSMBCLIENT_PICOBJS) +	@-$(AR) -rc $@ $(LIBSMBCLIENT_PICOBJS)  bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS)  	@echo Linking bigballofmud shared library $@ -	$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \ +	@$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \  		@SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) $(PASSDBLIBS) $(ADSLIBS)  # It would be nice to build a static bigballofmud too, but when I try @@ -1079,10 +1091,10 @@ bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \  bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)  	@echo "Linking shared library $@" -	$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc +	@$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc  bin/libmsrpc.a: $(LIBMSRPC_PICOBJ) -	-$(AR) -rc $@ $(LIBMSRPC_PICOBJ)  +	@-$(AR) -rc $@ $(LIBMSRPC_PICOBJ)   bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy  	@echo Linking $@ diff --git a/source3/include/fake_file.h b/source3/include/fake_file.h new file mode 100644 index 0000000000..3fe60072e9 --- /dev/null +++ b/source3/include/fake_file.h @@ -0,0 +1,46 @@ +/*  +   Unix SMB/CIFS implementation. +   FAKE FILE suppport, for faking up special files windows want access to +   Copyright (C) Stefan (metze) Metzmacher	2003 +    +   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 +   the Free Software Foundation; either version 2 of the License, or +   (at your option) any later version. +    +   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. +    +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _FAKE_FILE_H +#define _FAKE_FILE_H + +enum FAKE_FILE_TYPE { +	FAKE_FILE_TYPE_NONE = 0, +	FAKE_FILE_TYPE_QUOTA	 +}; + +#define FAKE_FILE_NAME_QUOTA	"\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION" + +typedef struct _FAKE_FILE_HANDLE { +	enum FAKE_FILE_TYPE type; +	TALLOC_CTX *mem_ctx; +	void *pd; /* for private data */ +	void (*free_pd)(void **pd); /* free private_data */ +} FAKE_FILE_HANDLE; + +typedef struct _FAKE_FILE { +	const char *name; +	enum FAKE_FILE_TYPE type; +	void *(*init_pd)(TALLOC_CTX *men_ctx); +	void (*free_pd)(void **pd); +} FAKE_FILE; + + +#endif /* _FAKE_FILE_H */ diff --git a/source3/include/ntquotas.h b/source3/include/ntquotas.h new file mode 100644 index 0000000000..1425e59bb8 --- /dev/null +++ b/source3/include/ntquotas.h @@ -0,0 +1,97 @@ +/*  +   Unix SMB/CIFS implementation. +   NT QUOTA code constants +   Copyright (C) Stefan (metze) Metzmacher	2003 +    +   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 +   the Free Software Foundation; either version 2 of the License, or +   (at your option) any later version. +    +   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. +    +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _NTQUOTAS_H +#define _NTQUOTAS_H + +/*  + * details for Quota Flags: + *  + * 0x20 Log Limit: log if the user exceeds his Hard Quota + * 0x10 Log Warn:  log if the user exceeds his Soft Quota + * 0x02 Deny Disk: deny disk access when the user exceeds his Hard Quota + * 0x01 Enable Quotas: enable quota for this fs + * + */ + +#define QUOTAS_ENABLED		0x0001 +#define QUOTAS_DENY_DISK	0x0002 +#define QUOTAS_LOG_VIOLATIONS	0x0004 +#define CONTENT_INDEX_DISABLED	0x0008 +#define QUOTAS_LOG_THRESHOLD	0x0010 +#define QUOTAS_LOG_LIMIT	0x0020 +#define LOG_VOLUME_THRESHOLD	0x0040 +#define LOG_VOLUME_LIMIT	0x0080 +#define QUOTAS_INCOMPLETE	0x0100 +#define QUOTAS_REBUILDING	0x0200 +#define QUOTAS_0400		0x0400 +#define QUOTAS_0800		0x0800 +#define QUOTAS_1000		0x1000 +#define QUOTAS_2000		0x2000 +#define QUOTAS_4000		0x4000 +#define QUOTAS_8000		0x8000 + +#define SMB_NTQUOTAS_NO_LIMIT	((SMB_BIG_UINT)(-1)) +#define SMB_NTQUOTAS_NO_ENTRY	((SMB_BIG_UINT)(-2)) +#define SMB_NTQUOTAS_NO_SPACE	((SMB_BIG_UINT)(0)) +#define SMB_NTQUOTAS_1_B	(SMB_BIG_UINT)0x0000000000000001 +#define SMB_NTQUOTAS_1KB	(SMB_BIG_UINT)0x0000000000000400 +#define SMB_NTQUOTAS_1MB	(SMB_BIG_UINT)0x0000000000100000 +#define SMB_NTQUOTAS_1GB	(SMB_BIG_UINT)0x0000000040000000 +#define SMB_NTQUOTAS_1TB	(SMB_BIG_UINT)0x0000010000000000 +#define SMB_NTQUOTAS_1PB	(SMB_BIG_UINT)0x0004000000000000 +#define SMB_NTQUOTAS_1EB	(SMB_BIG_UINT)0x1000000000000000 + +enum SMB_QUOTA_TYPE { +	SMB_INVALID_QUOTA_TYPE = -1, +	SMB_USER_FS_QUOTA_TYPE = 1, +	SMB_USER_QUOTA_TYPE = 2, +	SMB_GROUP_FS_QUOTA_TYPE = 3,/* not used yet */ +	SMB_GROUP_QUOTA_TYPE = 4 /* not in use yet, maybe for disk_free queries */ +}; + +typedef struct _SMB_NTQUOTA_STRUCT { +	enum SMB_QUOTA_TYPE qtype; +	SMB_BIG_UINT usedspace; +	SMB_BIG_UINT softlim; +	SMB_BIG_UINT hardlim; +	enum SMB_QUOTA_TYPE qflags; +	DOM_SID sid; +} SMB_NTQUOTA_STRUCT; + +typedef struct _SMB_NTQUOTA_LIST { +	struct _SMB_NTQUOTA_LIST *prev,*next; +	TALLOC_CTX *mem_ctx; +	uid_t uid; +	SMB_NTQUOTA_STRUCT *quotas; +} SMB_NTQUOTA_LIST; + +typedef struct _SMB_NTQUOTA_HANDLE { +	BOOL valid; +	SMB_NTQUOTA_LIST *quota_list; +	SMB_NTQUOTA_LIST *tmp_list; +} SMB_NTQUOTA_HANDLE; + +#define CHECK_NTQUOTA_HANDLE_OK(fsp,conn)	(FNUM_OK(fsp,conn) &&\ +	 (fsp)->fake_file_handle &&\ +	 ((fsp)->fake_file_handle->type == FAKE_FILE_TYPE_QUOTA) &&\ +	 (fsp)->fake_file_handle->pd) + +#endif /*_NTQUOTAS_H */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 02b5b9435e..62cc95ecb0 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -238,6 +238,8 @@ typedef struct nttime_info  #define MAXSUBAUTHS 15 /* max sub authorities in a SID */  #endif +#define SID_MAX_SIZE ((size_t)(8+(MAXSUBAUTHS*4))) +  /* SID Types */  enum SID_NAME_USE  { @@ -366,6 +368,7 @@ typedef struct  	SMB_STRUCT_STAT *statinfo;  } smb_filename; +#include "fake_file.h"  typedef struct files_struct  { @@ -402,6 +405,8 @@ typedef struct files_struct  	char *fsp_name;  } files_struct; +#include "ntquotas.h" +  /* used to hold an arbitrary blob of data */  typedef struct data_blob {  	uint8 *data; @@ -972,23 +977,23 @@ struct bitmap {  #define TRANSACT_WAITNAMEDPIPEHANDLESTATE 0x53  /* These are the TRANS2 sub commands */ -#define TRANSACT2_OPEN                        0 -#define TRANSACT2_FINDFIRST                   1 -#define TRANSACT2_FINDNEXT                    2 -#define TRANSACT2_QFSINFO                     3 -#define TRANSACT2_SETFSINFO                   4 -#define TRANSACT2_QPATHINFO                   5 -#define TRANSACT2_SETPATHINFO                 6 -#define TRANSACT2_QFILEINFO                   7 -#define TRANSACT2_SETFILEINFO                 8 -#define TRANSACT2_FSCTL                       9 -#define TRANSACT2_IOCTL                     0xA -#define TRANSACT2_FINDNOTIFYFIRST           0xB -#define TRANSACT2_FINDNOTIFYNEXT            0xC -#define TRANSACT2_MKDIR                     0xD -#define TRANSACT2_SESSION_SETUP             0xE -#define TRANSACT2_GET_DFS_REFERRAL         0x10 -#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11 +#define TRANSACT2_OPEN				0x00 +#define TRANSACT2_FINDFIRST			0x01 +#define TRANSACT2_FINDNEXT			0x02 +#define TRANSACT2_QFSINFO			0x03 +#define TRANSACT2_SETFSINFO			0x04 +#define TRANSACT2_QPATHINFO			0x05 +#define TRANSACT2_SETPATHINFO			0x06 +#define TRANSACT2_QFILEINFO			0x07 +#define TRANSACT2_SETFILEINFO			0x08 +#define TRANSACT2_FSCTL				0x09 +#define TRANSACT2_IOCTL				0x0A +#define TRANSACT2_FINDNOTIFYFIRST		0x0B +#define TRANSACT2_FINDNOTIFYNEXT		0x0C +#define TRANSACT2_MKDIR				0x0D +#define TRANSACT2_SESSION_SETUP			0x0E +#define TRANSACT2_GET_DFS_REFERRAL		0x10 +#define TRANSACT2_REPORT_DFS_INCONSISTANCY	0x11  /* These are the NT transact sub commands. */  #define NT_TRANSACT_CREATE                1 @@ -997,6 +1002,13 @@ struct bitmap {  #define NT_TRANSACT_NOTIFY_CHANGE         4  #define NT_TRANSACT_RENAME                5  #define NT_TRANSACT_QUERY_SECURITY_DESC   6 +#define NT_TRANSACT_GET_USER_QUOTA	  7 +#define NT_TRANSACT_SET_USER_QUOTA	  8 + +/* These are the NT transact_get_user_quota sub commands */ +#define TRANSACT_GET_USER_QUOTA_LIST_CONTINUE	0x0000 +#define TRANSACT_GET_USER_QUOTA_LIST_START	0x0100 +#define TRANSACT_GET_USER_QUOTA_FOR_SID		0x0101  /* Relevant IOCTL codes */  #define IOCTL_QUERY_JOB_INFO      0x530060 @@ -1237,18 +1249,23 @@ struct bitmap {  #define RENAME_REPLACE_IF_EXISTS 1  /* Filesystem Attributes. */ -#define FILE_CASE_SENSITIVE_SEARCH 0x01 -#define FILE_CASE_PRESERVED_NAMES 0x02 -#define FILE_UNICODE_ON_DISK 0x04 +#define FILE_CASE_SENSITIVE_SEARCH      0x00000001 +#define FILE_CASE_PRESERVED_NAMES       0x00000002 +#define FILE_UNICODE_ON_DISK            0x00000004  /* According to cifs9f, this is 4, not 8 */  /* Acconding to testing, this actually sets the security attribute! */ -#define FILE_PERSISTENT_ACLS 0x08 -/* These entries added from cifs9f --tsb */ -#define FILE_FILE_COMPRESSION 0x10 -#define FILE_VOLUME_QUOTAS 0x20 -/* I think this is wrong. JRA #define FILE_DEVICE_IS_MOUNTED 0x20 */ -#define FILE_VOLUME_SPARSE_FILE 0x40 -#define FILE_VOLUME_IS_COMPRESSED 0x8000 +#define FILE_PERSISTENT_ACLS            0x00000008 +#define FILE_FILE_COMPRESSION           0x00000010 +#define FILE_VOLUME_QUOTAS              0x00000020 +#define FILE_SUPPORTS_SPARSE_FILES      0x00000040 +#define FILE_SUPPORTS_REPARSE_POINTS    0x00000080 +#define FILE_SUPPORTS_REMOTE_STORAGE    0x00000100 +#define FS_LFN_APIS                     0x00004000 +#define FILE_VOLUME_IS_COMPRESSED       0x00008000 +#define FILE_SUPPORTS_OBJECT_IDS        0x00010000 +#define FILE_SUPPORTS_ENCRYPTION        0x00020000 +#define FILE_NAMED_STREAMS              0x00040000 +#define FILE_READ_ONLY_VOLUME           0x00080000  /* ChangeNotify flags. */  #define FILE_NOTIFY_CHANGE_FILE        0x001 diff --git a/source3/include/trans2.h b/source3/include/trans2.h index 3468d3b995..2ccf83478b 100644 --- a/source3/include/trans2.h +++ b/source3/include/trans2.h @@ -206,7 +206,9 @@ Byte offset   Type     name                description  #define SMB_QUERY_FS_SIZE_INFO          0x103  #define SMB_QUERY_FS_DEVICE_INFO        0x104  #define SMB_QUERY_FS_ATTRIBUTE_INFO     0x105 - +#if 0 +#define SMB_QUERY_FS_QUOTA_INFO		 +#endif  #define l2_vol_fdateCreation 0  #define l2_vol_cch 4 @@ -320,7 +322,7 @@ Byte offset   Type     name                description  #define SMB_FS_SIZE_INFORMATION				1003  #define SMB_FS_DEVICE_INFORMATION			1004  #define SMB_FS_ATTRIBUTE_INFORMATION			1005 -#define SMB_FS_CONTROL_INFORMATION			1006 +#define SMB_FS_QUOTA_INFORMATION			1006  #define SMB_FS_FULL_SIZE_INFORMATION			1007  #define SMB_FS_OBJECTID_INFORMATION			1008 diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index e2f9f19f58..e561d15f61 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1226,12 +1226,12 @@ char *binary_string(char *buf, int len)  	return ret;  } -#if 0 +  /**   Just a typesafety wrapper for snprintf into a fstring.  **/ -static int fstr_sprintf(fstring s, const char *fmt, ...) +int fstr_sprintf(fstring s, const char *fmt, ...)  {  	va_list ap;  	int ret; @@ -1241,7 +1241,7 @@ static int fstr_sprintf(fstring s, const char *fmt, ...)  	va_end(ap);  	return ret;  } -#endif +  #ifndef HAVE_STRNDUP  /** diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 4eb5efe193..b771e135f4 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -375,9 +375,11 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)   Used in smbtorture.  ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess, +int cli_nt_create_full(struct cli_state *cli, const char *fname,  +		 uint32 CreatFlags, uint32 DesiredAccess,  		 uint32 FileAttributes, uint32 ShareAccess, -		 uint32 CreateDisposition, uint32 CreateOptions) +		 uint32 CreateDisposition, uint32 CreateOptions, +		 uint8 SecuityFlags)  {  	char *p;  	int len; @@ -393,9 +395,9 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA  	SSVAL(cli->outbuf,smb_vwv0,0xFF);  	if (cli->use_oplocks) -		SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); -	else -		SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); +		CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); +	 +	SIVAL(cli->outbuf,smb_ntcreate_Flags, CreatFlags);  	SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0);  	SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess);  	SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes); @@ -403,6 +405,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA  	SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition);  	SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions);  	SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); +	SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecuityFlags);  	p = smb_buf(cli->outbuf);  	/* this alignment and termination is critical for netapp filers. Don't change */ @@ -433,8 +436,8 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA  int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess)  { -	return cli_nt_create_full(cli, fname, DesiredAccess, 0, -				FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0); +	return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0, +				FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0);  }  /**************************************************************************** diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c new file mode 100644 index 0000000000..00fe189e9a --- /dev/null +++ b/source3/libsmb/clifsinfo.c @@ -0,0 +1,76 @@ +/*  +   Unix SMB/CIFS implementation. +   FS info functions +   Copyright (C) Stefan (metze) Metzmacher	2003 +    +   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 +   the Free Software Foundation; either version 2 of the License, or +   (at your option) any later version. +    +   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. +    +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) +{ +	BOOL ret = False; +	uint16 setup; +	char param[2]; +	char *rparam=NULL, *rdata=NULL; +	unsigned int rparam_count=0, rdata_count=0; + +	if (!cli||!fs_attr) +		smb_panic("cli_get_fs_attr_info() called with NULL Pionter!"); + +	setup = TRANSACT2_QFSINFO; +	 +	SSVAL(param,0,SMB_QUERY_FS_ATTRIBUTE_INFO); + +	if (!cli_send_trans(cli, SMBtrans2,  +		    NULL,  +		    0, 0, +		    &setup, 1, 0, +		    param, 2, 0, +		    NULL, 0, 560)) { +		goto cleanup; +	} +	 +	if (!cli_receive_trans(cli, SMBtrans2, +                              &rparam, &rparam_count, +                              &rdata, &rdata_count)) { +		goto cleanup; +	} + +	if (cli_is_error(cli)) { +		ret = False; +		goto cleanup; +	} else { +		ret = True; +	} + +	if (rdata_count < 12) { +		goto cleanup; +	} + +	*fs_attr = IVAL(rdata,0); + +	/* todo: but not yet needed  +	 *       return the other stuff +	 */ + +cleanup: +	SAFE_FREE(rparam); +	SAFE_FREE(rdata); + +	return ret;	 +} diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c new file mode 100644 index 0000000000..a56a6bd674 --- /dev/null +++ b/source3/libsmb/cliquota.c @@ -0,0 +1,633 @@ +/*  +   Unix SMB/CIFS implementation. +   client quota functions +   Copyright (C) Stefan (metze) Metzmacher	2003 +    +   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 +   the Free Software Foundation; either version 2 of the License, or +   (at your option) any later version. +    +   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. +    +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum) +{ +	*quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA, +		 0x00000016, DESIRED_ACCESS_PIPE, +		 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE, +		 FILE_OPEN, 0x00000000, 0x03); +		  +	if (*quota_fnum == (-1)) { +		return False;	 +	} + +	return True; +} + +void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list) +{ +	if (!qt_list) +		return; +		 +	if ((*qt_list)->mem_ctx) +		talloc_destroy((*qt_list)->mem_ctx); + +	(*qt_list) = NULL; + +	return;	 +} + +static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt) +{ +	int sid_len; +	SMB_NTQUOTA_STRUCT qt; + +	ZERO_STRUCT(qt); + +	if (!rdata||!offset||!pqt) +		smb_panic("parse_quota_record: called with NULL POINTER!\n"); + +	if (rdata_count < 40) { +		return False; +	} +		 +	/* offset to next quota record. +	 * 4 bytes IVAL(rdata,0) +	 * unused here... +	 */ +	*offset = IVAL(rdata,0); + +	/* sid len */ +	sid_len = IVAL(rdata,4); + +	if (rdata_count < 40+sid_len) { +		return False;		 +	} + +	/* unknown 8 bytes in pdata  +	 * maybe its the change time in NTTIME +	 */ + +	/* the used space 8 bytes (SMB_BIG_UINT)*/ +	qt.usedspace = (SMB_BIG_UINT)IVAL(rdata,16); +#ifdef LARGE_SMB_OFF_T +	qt.usedspace |= (((SMB_BIG_UINT)IVAL(rdata,20)) << 32); +#else /* LARGE_SMB_OFF_T */ +	if ((IVAL(rdata,20) != 0)&& +		((qt.usedspace != 0xFFFFFFFF)|| +		(IVAL(rdata,20)!=0xFFFFFFFF)))) { +		/* more than 32 bits? */ +		return False; +	} +#endif /* LARGE_SMB_OFF_T */ + +	/* the soft quotas 8 bytes (SMB_BIG_UINT)*/ +	qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24); +#ifdef LARGE_SMB_OFF_T +	qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ +	if ((IVAL(rdata,28) != 0)&& +		((qt.softlim != 0xFFFFFFFF)|| +		(IVAL(rdata,28)!=0xFFFFFFFF)))) { +		/* more than 32 bits? */ +		return False; +	} +#endif /* LARGE_SMB_OFF_T */ + +	/* the hard quotas 8 bytes (SMB_BIG_UINT)*/ +	qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32); +#ifdef LARGE_SMB_OFF_T +	qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ +	if ((IVAL(rdata,36) != 0)&& +		((qt.hardlim != 0xFFFFFFFF)|| +		(IVAL(rdata,36)!=0xFFFFFFFF)))) { +		/* more than 32 bits? */ +		return False; +	} +#endif /* LARGE_SMB_OFF_T */ +	 +	sid_parse(rdata+40,sid_len,&qt.sid); + +	qt.qtype = SMB_USER_QUOTA_TYPE; + +	*pqt = qt; + +	return True; +} + +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; +} + +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; +} + +BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list) +{ +	BOOL ret = False; +	uint16 setup; +	char params[16]; +	char *rparam=NULL, *rdata=NULL; +	unsigned int rparam_count=0, rdata_count=0; +	unsigned int offset; +	const char *curdata = NULL; +	unsigned int curdata_count = 0; +	TALLOC_CTX *mem_ctx = NULL; +	SMB_NTQUOTA_STRUCT qt; +	SMB_NTQUOTA_LIST *tmp_list_ent; + +	if (!cli||!pqt_list) +		smb_panic("cli_list_user_quota() called with NULL Pointer!"); + +	setup = NT_TRANSACT_GET_USER_QUOTA; + +	SSVAL(params, 0,quota_fnum); +	SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START); +	SIVAL(params, 4,0x00000000); +	SIVAL(params, 8,0x00000000); +	SIVAL(params,12,0x00000000); +	 +	if (!cli_send_nt_trans(cli,  +			       NT_TRANSACT_GET_USER_QUOTA,  +			       0,  +			       &setup, 1, 0, +			       params, 16, 4, +			       NULL, 0, 2048)) { +		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 (rdata_count == 0) { +		*pqt_list = NULL; +		return True; +	} + +	if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) { +		DEBUG(0,("talloc_init() failed\n")); +		return (-1); +	} + +	offset = 1; +	for (curdata=rdata,curdata_count=rdata_count; +		((curdata)&&(curdata_count>=8)&&(offset>0)); +		curdata +=offset,curdata_count -= offset) { +		ZERO_STRUCT(qt); +		if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { +			DEBUG(1,("Failed to parse the quota record\n")); +			goto cleanup; +		} + +		if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { +			DEBUG(0,("talloc_zero() failed\n")); +			return (-1); +		} + +		if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { +			DEBUG(0,("talloc_zero() failed\n")); +			return (-1); +		} + +		memcpy(tmp_list_ent->quotas,&qt,sizeof(qt)); +		tmp_list_ent->mem_ctx = mem_ctx;		 + +		DLIST_ADD((*pqt_list),tmp_list_ent); +	} + +	SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE);	 +	while(1) { +		if (!cli_send_nt_trans(cli,  +				       NT_TRANSACT_GET_USER_QUOTA,  +				       0,  +				       &setup, 1, 0, +				       params, 16, 4, +				       NULL, 0, 2048)) { +			DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); +			goto cleanup; +		} +		 +		SAFE_FREE(rparam); +		SAFE_FREE(rdata); +		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 (rdata_count == 0) { +			break;	 +		} + +		offset = 1; +		for (curdata=rdata,curdata_count=rdata_count; +			((curdata)&&(curdata_count>=8)&&(offset>0)); +			curdata +=offset,curdata_count -= offset) { +			ZERO_STRUCT(qt); +			if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { +				DEBUG(1,("Failed to parse the quota record\n")); +				goto cleanup; +			} + +			if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { +				DEBUG(0,("talloc_zero() failed\n")); +				talloc_destroy(mem_ctx); +				goto cleanup; +			} +	 +			if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { +				DEBUG(0,("talloc_zero() failed\n")); +				talloc_destroy(mem_ctx); +				goto cleanup; +			} +	 +			memcpy(tmp_list_ent->quotas,&qt,sizeof(qt)); +			tmp_list_ent->mem_ctx = mem_ctx;		 +	 +			DLIST_ADD((*pqt_list),tmp_list_ent); +		} +	} + +  +	ret = True; + cleanup: +	SAFE_FREE(rparam); +	SAFE_FREE(rdata); +  +	return ret; +} + +BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ +	BOOL ret = False; +	uint16 setup; +	char param[2]; +	char *rparam=NULL, *rdata=NULL; +	unsigned int rparam_count=0, rdata_count=0; +	SMB_NTQUOTA_STRUCT qt; +	ZERO_STRUCT(qt); + +	if (!cli||!pqt) +		smb_panic("cli_get_fs_quota_info() called with NULL Pointer!"); + +	setup = TRANSACT2_QFSINFO; +	 +	SSVAL(param,0,SMB_FS_QUOTA_INFORMATION); +	 +	if (!cli_send_trans(cli, SMBtrans2,  +		    NULL,  +		    0, 0, +		    &setup, 1, 0, +		    param, 2, 0, +		    NULL, 0, 560)) { +		goto cleanup; +	} +	 +	if (!cli_receive_trans(cli, SMBtrans2, +                              &rparam, &rparam_count, +                              &rdata, &rdata_count)) { +		goto cleanup; +	} + +	if (cli_is_error(cli)) { +		ret = False; +		goto cleanup; +	} else { +		ret = True; +	} + +	if (rdata_count < 48) { +		goto cleanup; +	} +	 +	/* unknown_1 24 NULL bytes in pdata*/ + +	/* the soft quotas 8 bytes (SMB_BIG_UINT)*/ +	qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24); +#ifdef LARGE_SMB_OFF_T +	qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ +	if ((IVAL(rdata,28) != 0)&& +		((qt.softlim != 0xFFFFFFFF)|| +		(IVAL(rdata,28)!=0xFFFFFFFF)))) { +		/* more than 32 bits? */ +		goto cleanup; +	} +#endif /* LARGE_SMB_OFF_T */ + +	/* the hard quotas 8 bytes (SMB_BIG_UINT)*/ +	qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32); +#ifdef LARGE_SMB_OFF_T +	qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ +	if ((IVAL(rdata,36) != 0)&& +		((qt.hardlim != 0xFFFFFFFF)|| +		(IVAL(rdata,36)!=0xFFFFFFFF)))) { +		/* more than 32 bits? */ +		goto cleanup; +	} +#endif /* LARGE_SMB_OFF_T */ + +	/* quota_flags 2 bytes **/ +	qt.qflags = SVAL(rdata,40); + +	qt.qtype = SMB_USER_FS_QUOTA_TYPE; + +	*pqt = qt; + +	ret = True; +cleanup: +	SAFE_FREE(rparam); +	SAFE_FREE(rdata); + +	return ret;	 +} + +BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ +	BOOL ret = False; +	uint16 setup; +	char param[4]; +	char data[48]; +	char *rparam=NULL, *rdata=NULL; +	unsigned int rparam_count=0, rdata_count=0; +	SMB_NTQUOTA_STRUCT qt; +	ZERO_STRUCT(qt); +	memset(data,'\0',48); + +	if (!cli||!pqt) +		smb_panic("cli_set_fs_quota_info() called with NULL Pointer!"); + +	setup = TRANSACT2_SETFSINFO; + +	SSVAL(param,0,quota_fnum); +	SSVAL(param,2,SMB_FS_QUOTA_INFORMATION); + +	/* Unknown1 24 NULL bytes*/ + +	/* Default Soft Quota 8 bytes */ +	SBIG_UINT(data,24,pqt->softlim); + +	/* Default Hard Quota 8 bytes */ +	SBIG_UINT(data,32,pqt->hardlim); + +	/* Quota flag 2 bytes */ +	SSVAL(data,40,pqt->qflags); + +	/* Unknown3 6 NULL bytes */ + +	if (!cli_send_trans(cli, SMBtrans2,  +		    NULL,  +		    0, 0, +		    &setup, 1, 0, +		    param, 4, 0, +		    data, 48, 0)) { +		goto cleanup; +	} +	 +	if (!cli_receive_trans(cli, SMBtrans2, +                              &rparam, &rparam_count, +                              &rdata, &rdata_count)) { +		goto cleanup; +	} + +	if (cli_is_error(cli)) { +		ret = False; +		goto cleanup; +	} else { +		ret = True; +	} + +cleanup: +	SAFE_FREE(rparam); +	SAFE_FREE(rdata); + +	return ret;	 +} + +static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric) +{ +	static fstring buffer; +	 +	memset(buffer,'\0',sizeof(buffer)); + +	if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) { +		fstr_sprintf(buffer,"NO LIMIT"); +		return buffer; +	} +#if defined(HAVE_LONGLONG) +	fstr_sprintf(buffer,"%llu",val); +#else +	fstr_sprintf(buffer,"%lu",val); +#endif	 +	return buffer; +} + +void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) +{ +	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"AS_ENABLED)||(qt->qflags"AS_DENY_DISK))?"On":"Off"); +				d_printf(" Deny Disk:      %s\n",(qt->qflags"AS_DENY_DISK)?"On":"Off"); +				d_printf(" Log Soft Limit: %s\n",(qt->qflags"AS_LOG_THRESHOLD)?"On":"Off"); +				d_printf(" Log Hard Limit: %s\n",(qt->qflags"AS_LOG_LIMIT)?"On":"Off"); +			} +			break; +		case SMB_USER_QUOTA_TYPE: +			{ +				fstring username_str = {0}; +				 +				if (_sidtostring) { +					_sidtostring(username_str,&qt->sid,_numeric); +				} else { +					fstrcpy(username_str,sid_string_static(&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); +			return; +	} +} + +void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, 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); +	}	 +} diff --git a/source3/python/py_smb.c b/source3/python/py_smb.c index 8d81176e4d..d37b73cceb 100644 --- a/source3/python/py_smb.c +++ b/source3/python/py_smb.c @@ -165,8 +165,8 @@ static PyObject *py_smb_nt_create_andx(PyObject *self, PyObject *args,  		return NULL;  	result = cli_nt_create_full( -		cli->cli, filename, desired_access, file_attributes, -		share_access, create_disposition, create_options); +		cli->cli, filename, 0, desired_access, file_attributes, +		share_access, create_disposition, create_options, 0);  	if (cli_is_error(cli->cli)) {  		PyErr_SetString(PyExc_RuntimeError, "nt_create_andx failed"); diff --git a/source3/torture/nbio.c b/source3/torture/nbio.c index 2d519b40ba..d8d3ca0c09 100644 --- a/source3/torture/nbio.c +++ b/source3/torture/nbio.c @@ -148,12 +148,12 @@ void nb_createx(char *fname,  		desired_access = FILE_READ_DATA | FILE_WRITE_DATA;  	} -	fd = cli_nt_create_full(c, fname,  +	fd = cli_nt_create_full(c, fname, 0,   				desired_access,  				0x0,  				FILE_SHARE_READ|FILE_SHARE_WRITE,   				create_disposition,  -				create_options); +				create_options, 0);  	if (fd == -1 && handle != -1) {  		printf("ERROR: cli_nt_create_full failed for %s - %s\n",  		       fname, cli_errstr(c)); diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 5ff7c3bb2d..00d5b86ff8 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -2778,9 +2778,9 @@ static BOOL run_deletetest(int dummy)  	cli_setatr(cli1, fname, 0, 0);  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, +	fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,  				   FILE_SHARE_DELETE, FILE_OVERWRITE_IF,  -				   FILE_DELETE_ON_CLOSE); +				   FILE_DELETE_ON_CLOSE, 0);  	if (fnum1 == -1) {  		printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2808,9 +2808,9 @@ static BOOL run_deletetest(int dummy)  	cli_setatr(cli1, fname, 0, 0);  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, +	fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,  				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,  -				   FILE_OVERWRITE_IF, 0); +				   FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2846,8 +2846,8 @@ static BOOL run_deletetest(int dummy)  	cli_setatr(cli1, fname, 0, 0);  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2858,8 +2858,8 @@ static BOOL run_deletetest(int dummy)  	/* This should fail with a sharing violation - open for delete is only compatible  	   with SHARE_DELETE. */ -	fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, -			FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0); +	fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, +			FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);  	if (fnum2 != -1) {  		printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname); @@ -2869,8 +2869,8 @@ static BOOL run_deletetest(int dummy)  	/* This should succeed. */ -	fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, -			FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); +	fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, +			FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);  	if (fnum2 == -1) {  		printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2914,8 +2914,8 @@ static BOOL run_deletetest(int dummy)  	cli_setatr(cli1, fname, 0, 0);  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, -			FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, +			FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2924,8 +2924,8 @@ static BOOL run_deletetest(int dummy)  	}  	/* This should succeed. */ -	fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, -			FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); +	fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, +			FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);  	if (fnum2 == -1) {  		printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));  		correct = False; @@ -2945,8 +2945,9 @@ static BOOL run_deletetest(int dummy)  	}  	/* This should fail - no more opens once delete on close set. */ -	fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, -				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); +	fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, +				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, +				   FILE_OPEN, 0, 0);  	if (fnum2 != -1) {  		printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );  		correct = False; @@ -2991,9 +2992,9 @@ static BOOL run_deletetest(int dummy)  	cli_setatr(cli1, fname, 0, 0);  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA, +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,  				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, -				   FILE_OVERWRITE_IF, 0); +				   FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3021,8 +3022,8 @@ static BOOL run_deletetest(int dummy)  	cli_setatr(cli1, fname, 0, 0);  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, -				   FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, +				   FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3077,8 +3078,9 @@ static BOOL run_deletetest(int dummy)  	cli_sockopt(cli1, sockops); -	fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, -				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, +				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, +				   FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3086,8 +3088,9 @@ static BOOL run_deletetest(int dummy)  		goto fail;  	} -	fnum2 = cli_nt_create_full(cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, -				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, +				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, +				   FILE_OPEN, 0, 0);  	if (fnum2 == -1) {  		printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3123,8 +3126,8 @@ static BOOL run_deletetest(int dummy)  		printf("eighth delete on close test succeeded.\n");  	/* This should fail - we need to set DELETE_ACCESS. */ -	fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA, -				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE); +	fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA, +				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);  	if (fnum1 != -1) {  		printf("[9] open of %s succeeded should have failed!\n", fname); @@ -3134,8 +3137,8 @@ static BOOL run_deletetest(int dummy)  	printf("ninth delete on close test succeeded.\n"); -	fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, -				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, +				   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);  	if (fnum1 == -1) {  		printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));  		correct = False; @@ -3243,20 +3246,20 @@ static BOOL run_xcopy(int dummy)  		return False;  	} -	fnum1 = cli_nt_create_full(cli1, fname,  +	fnum1 = cli_nt_create_full(cli1, fname, 0,  				   FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,  				   FILE_SHARE_NONE, FILE_OVERWRITE_IF,  -				   0x4044); +				   0x4044, 0);  	if (fnum1 == -1) {  		printf("First open failed - %s\n", cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli1, fname,  +	fnum2 = cli_nt_create_full(cli1, fname, 0,  				   SECOND_DESIRED_ACCESS, 0,  				   FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,  -				   0x200000); +				   0x200000, 0);  	if (fnum2 == -1) {  		printf("second open failed - %s\n", cli_errstr(cli1));  		return False; @@ -3288,8 +3291,8 @@ static BOOL run_rename(int dummy)  	cli_unlink(cli1, fname);  	cli_unlink(cli1, fname1); -	fnum1 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_READ, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("First open failed - %s\n", cli_errstr(cli1)); @@ -3310,11 +3313,11 @@ static BOOL run_rename(int dummy)  	cli_unlink(cli1, fname);  	cli_unlink(cli1, fname1); -	fnum1 = cli_nt_create_full(cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, +	fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,  #if 0 -				   FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +				   FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  #else -				   FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0); +				   FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);  #endif  	if (fnum1 == -1) { @@ -3337,8 +3340,8 @@ static BOOL run_rename(int dummy)  	cli_unlink(cli1, fname);  	cli_unlink(cli1, fname1); -	fnum1 = cli_nt_create_full(cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("Third open failed - %s\n", cli_errstr(cli1)); @@ -3350,8 +3353,8 @@ static BOOL run_rename(int dummy)    {    int fnum2; -	fnum2 = cli_nt_create_full(cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum2 == -1) {  		printf("Fourth open failed - %s\n", cli_errstr(cli1)); @@ -3405,8 +3408,8 @@ static BOOL run_pipe_number(int dummy)  	cli_sockopt(cli1, sockops);  	while(1) { -		fnum = cli_nt_create_full(cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0); +		fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);  		if (fnum == -1) {  			printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1)); @@ -3594,16 +3597,16 @@ static BOOL run_opentest(int dummy)  	printf("TEST #1 testing 2 non-io opens (no delete)\n"); -	fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OPEN_IF, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);  	if (fnum2 == -1) {  		printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3625,16 +3628,16 @@ static BOOL run_opentest(int dummy)  	printf("TEST #2 testing 2 non-io opens (first with delete)\n"); -	fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OPEN_IF, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);  	if (fnum2 == -1) {  		printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3656,16 +3659,16 @@ static BOOL run_opentest(int dummy)  	printf("TEST #3 testing 2 non-io opens (second with delete)\n"); -	fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OPEN_IF, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);  	if (fnum2 == -1) {  		printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3687,16 +3690,16 @@ static BOOL run_opentest(int dummy)  	printf("TEST #4 testing 2 non-io opens (both with delete)\n"); -	fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OPEN_IF, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);  	if (fnum2 != -1) {  		printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2)); @@ -3716,16 +3719,16 @@ static BOOL run_opentest(int dummy)  	printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n"); -	fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_DELETE, FILE_OPEN_IF, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);  	if (fnum2 == -1) {  		printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3748,16 +3751,16 @@ static BOOL run_opentest(int dummy)  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_READ, FILE_OPEN_IF, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);  	if (fnum2 == -1) {  		printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3780,16 +3783,16 @@ static BOOL run_opentest(int dummy)  	cli_unlink(cli1, fname); -	fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +	fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  	if (fnum1 == -1) {  		printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));  		return False;  	} -	fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, -				   FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0); +	fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, +				   FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);  	if (fnum2 != -1) {  		printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2)); @@ -3893,8 +3896,8 @@ static BOOL run_openattrtest(int dummy)  	for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {  		cli_setatr(cli1, fname, 0, 0);  		cli_unlink(cli1, fname); -		fnum1 = cli_nt_create_full(cli1, fname,FILE_WRITE_DATA, open_attrs_table[i], -				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); +		fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i], +				   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);  		if (fnum1 == -1) {  			printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1)); @@ -3907,8 +3910,8 @@ static BOOL run_openattrtest(int dummy)  		}  		for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) { -			fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j], -					   FILE_SHARE_NONE, FILE_OVERWRITE, 0); +			fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j], +					   FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);  			if (fnum1 == -1) {  				for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) { @@ -4220,8 +4223,8 @@ static BOOL run_dirtest1(int dummy)  	for (i=0;i<1000;i++) {  		fstring fname;  		slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i); -		fnum = cli_nt_create_full(cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE, -				   FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0); +		fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE, +				   FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);  		if (fnum == -1) {  			fprintf(stderr,"Failed to open %s\n", fname);  			return False; diff --git a/source3/torture/utable.c b/source3/torture/utable.c index 74d5f164c0..3ec5932b79 100644 --- a/source3/torture/utable.c +++ b/source3/torture/utable.c @@ -144,11 +144,11 @@ BOOL torture_casetable(int dummy)  		printf("%04x (%c)\n", c, isprint(c)?c:'.');  		fname = form_name(c); -		fnum = cli_nt_create_full(cli, fname,  +		fnum = cli_nt_create_full(cli, fname, 0,  					  GENERIC_ALL_ACCESS,   					  FILE_ATTRIBUTE_NORMAL,  					  FILE_SHARE_NONE, -					  FILE_OPEN_IF, 0); +					  FILE_OPEN_IF, 0, 0);  		if (fnum == -1) {  			printf("Failed to create file with char %04x\n", c); diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c new file mode 100644 index 0000000000..c5d0aa869b --- /dev/null +++ b/source3/utils/smbcquotas.c @@ -0,0 +1,545 @@ +/*  +   Unix SMB/CIFS implementation. +   QUOTA get/set utility +    +   Copyright (C) Andrew Tridgell		2000 +   Copyright (C) Tim Potter			2000 +   Copyright (C) Jeremy Allison			2000 +   Copyright (C) Stefan (metze) Metzmacher	2003 +    +   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 +   the Free Software Foundation; either version 2 of the License, or +   (at your option) any later version. +    +   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. +    +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static pstring server; + +/* numeric is set when the user wants numeric SIDs and ACEs rather +   than going via LSA calls to resolve them */ +static BOOL numeric; +static BOOL verbose; + +enum todo_values {NOOP_QUOTA=0,FS_QUOTA,USER_QUOTA,LIST_QUOTA,SET_QUOTA}; +enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR}; + +static struct cli_state *cli_ipc = NULL; +static POLICY_HND pol; +static BOOL got_policy_hnd; + +static struct cli_state *connect_one(const char *share); + +/* Open cli connection and policy handle */ + +static BOOL cli_open_policy_hnd(void) +{ +	/* Initialise cli LSA connection */ + +	if (!cli_ipc) { +		cli_ipc = connect_one("IPC$"); +		if (!cli_nt_session_open (cli_ipc, PI_LSARPC)) { +				return False; +		} +	} +	 +	/* Open policy handle */ + +	if (!got_policy_hnd) { + +		/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, +		   but NT sends 0x2000000 so we might as well do it too. */ + +		if (!NT_STATUS_IS_OK(cli_lsa_open_policy(cli_ipc, cli_ipc->mem_ctx, True,  +							 GENERIC_EXECUTE_ACCESS, &pol))) { +			return False; +		} + +		got_policy_hnd = True; +	} +	 +	return True; +} + +/* convert a SID to a string, either numeric or username/group */ +static void SidToString(fstring str, DOM_SID *sid, BOOL _numeric) +{ +	char **domains = NULL; +	char **names = NULL; +	uint32 *types = NULL; + +	sid_to_string(str, sid); + +	if (_numeric) return; + +	/* Ask LSA to convert the sid to a name */ + +	if (!cli_open_policy_hnd() || +	    !NT_STATUS_IS_OK(cli_lsa_lookup_sids(cli_ipc, cli_ipc->mem_ctx,   +						 &pol, 1, sid, &domains,  +						 &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 */ +static BOOL StringToSid(DOM_SID *sid, const char *str) +{ +	uint32 *types = NULL; +	DOM_SID *sids = NULL; +	BOOL result = True; + +	if (strncmp(str, "S-", 2) == 0) { +		return string_to_sid(sid, str); +	} + +	if (!cli_open_policy_hnd() || +	    !NT_STATUS_IS_OK(cli_lsa_lookup_names(cli_ipc, cli_ipc->mem_ctx,  +						  &pol, 1, &str, &sids,  +						  &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}; + +static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA_TYPE *qtype, int *cmd, SMB_NTQUOTA_STRUCT *pqt) +{ +	char *p = set_str,*p2; +	int todo; +	BOOL stop = False; +	BOOL enable = False; +	BOOL deny = False; +	 +	if (strncasecmp(set_str,"UQLIM:",6)==0) { +		p += 6; +		*qtype = SMB_USER_QUOTA_TYPE; +		*cmd = QUOTA_SETLIM; +		todo = PARSE_LIM; +		if ((p2=strstr(p,":"))==NULL) { +			return -1; +		} +		 +		*p2 = '\0'; +		p2++; +		 +		fstrcpy(username_str,p); +		p = p2; +	} else if (strncasecmp(set_str,"FSQLIM:",7)==0) { +		p +=7; +		*qtype = SMB_USER_FS_QUOTA_TYPE; +		*cmd = QUOTA_SETLIM; +		todo = PARSE_LIM; +	} else if (strncasecmp(set_str,"FSQFLAGS:",9)==0) { +		p +=9; +		todo = PARSE_FLAGS; +		*qtype = SMB_USER_FS_QUOTA_TYPE; +		*cmd = QUOTA_SETFLAGS; +	} else { +		return -1; +	} + +	switch (todo) { +		case PARSE_LIM: +#if defined(HAVE_LONGLONG) +			if (sscanf(p,"%llu/%llu",&pqt->softlim,&pqt->hardlim)!=2) { +#else +			if (sscanf(p,"%lu/%lu",&pqt->softlim,&pqt->hardlim)!=2) { +#endif +				return -1; +			} +			 +			break; +		case PARSE_FLAGS: +			while (!stop) { + +				if ((p2=strstr(p,"/"))==NULL) { +					stop = True; +				} else { +					*p2 = '\0'; +					p2++; +				} + +				if (strncasecmp(p,"QUOTA_ENABLED",13)==0) { +					enable = True; +				} else if (strncasecmp(p,"DENY_DISK",9)==0) { +					deny = True; +				} else if (strncasecmp(p,"LOG_SOFTLIMIT",13)==0) { +					pqt->qflags |= QUOTAS_LOG_THRESHOLD; +				} else if (strncasecmp(p,"LOG_HARDLIMIT",13)==0) { +					pqt->qflags |= QUOTAS_LOG_LIMIT; +				} else { +					return -1; +				} + +				p=p2; +			} + +			if (deny) { +				pqt->qflags |= QUOTAS_DENY_DISK; +			} else if (enable) { +				pqt->qflags |= QUOTAS_ENABLED; +			} +			 +			break;	 +	} + +	return 0; +} + +static int do_quota(struct cli_state *cli, enum SMB_QUOTA_TYPE qtype, uint16 cmd, pstring username_str, SMB_NTQUOTA_STRUCT *pqt) +{ +	uint32 fs_attrs = 0; +	int quota_fnum = 0; +	SMB_NTQUOTA_LIST *qtl = NULL; +	SMB_NTQUOTA_STRUCT qt; +	ZERO_STRUCT(qt); + +	if (!cli_get_fs_attr_info(cli, &fs_attrs)) { +		d_printf("Failed to get the filesystem attributes %s.\n", +			cli_errstr(cli)); +		return -1; +	} + +	if (!(fs_attrs & FILE_VOLUME_QUOTAS)) { +		d_printf("Quotas are not supported by the server.\n"); +		return 0;	 +	} + +	if (!cli_get_quota_handle(cli, "a_fnum)) { +		d_printf("Failed to open \\%s  %s.\n", +			FAKE_FILE_NAME_QUOTA,cli_errstr(cli)); +		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; +			} +			 +			switch(cmd) { +				case QUOTA_GET: +					if (!cli_get_user_quota(cli, quota_fnum, &qt)) { +						d_printf("%s cli_get_user_quota %s\n", +							 cli_errstr(cli),username_str); +						return -1; +					} +					dump_ntquota(&qt,verbose,numeric,SidToString); +					break; +				case QUOTA_SETLIM: +					pqt->sid = qt.sid; +					if (!cli_set_user_quota(cli, quota_fnum, pqt)) { +						d_printf("%s cli_set_user_quota %s\n", +							 cli_errstr(cli),username_str); +						return -1; +					} +					if (!cli_get_user_quota(cli, quota_fnum, &qt)) { +						d_printf("%s cli_get_user_quota %s\n", +							 cli_errstr(cli),username_str); +						return -1; +					} +					dump_ntquota(&qt,verbose,numeric,SidToString); +					break; +				case QUOTA_LIST: +					if (!cli_list_user_quota(cli, quota_fnum, &qtl)) { +						d_printf("%s cli_set_user_quota %s\n", +							 cli_errstr(cli),username_str); +						return -1; +					} +					dump_ntquota_list(&qtl,verbose,numeric,SidToString); +					free_ntquota_list(&qtl);					 +					break; +				default: +					d_printf("Unknown Error\n"); +					return -1; +			}  +			break; +		case SMB_USER_FS_QUOTA_TYPE: +			switch(cmd) { +				case QUOTA_GET: +					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { +						d_printf("%s cli_get_fs_quota_info\n", +							 cli_errstr(cli)); +						return -1; +					} +					dump_ntquota(&qt,True,numeric,NULL); +					break; +				case QUOTA_SETLIM: +					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { +						d_printf("%s cli_get_fs_quota_info\n", +							 cli_errstr(cli)); +						return -1; +					} +					qt.softlim = pqt->softlim; +					qt.hardlim = pqt->hardlim; +					if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) { +						d_printf("%s cli_set_fs_quota_info\n", +							 cli_errstr(cli)); +						return -1; +					} +					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { +						d_printf("%s cli_get_fs_quota_info\n", +							 cli_errstr(cli)); +						return -1; +					} +					dump_ntquota(&qt,True,numeric,NULL); +					break; +				case QUOTA_SETFLAGS: +					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { +						d_printf("%s cli_get_fs_quota_info\n", +							 cli_errstr(cli)); +						return -1; +					} +					qt.qflags = pqt->qflags; +					if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) { +						d_printf("%s cli_set_fs_quota_info\n", +							 cli_errstr(cli)); +						return -1; +					} +					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { +						d_printf("%s cli_get_fs_quota_info\n", +							 cli_errstr(cli)); +						return -1; +					} +					dump_ntquota(&qt,True,numeric,NULL); +					break; +				default: +					d_printf("Unknown Error\n"); +					return -1; +			} 		 +			break; +		default: +			d_printf("Unknown Error\n"); +			return -1; +	} + +	cli_close(cli, quota_fnum); + +	return 0; +} + +/*****************************************************  +return a connection to a server +*******************************************************/ +static struct cli_state *connect_one(const char *share) +{ +	struct cli_state *c; +	struct in_addr ip; +	NTSTATUS nt_status; +	zero_ip(&ip); +	 +	if (!cmdline_auth_info.got_pass) { +		char *pass = getpass("Password: "); +		if (pass) { +			pstrcpy(cmdline_auth_info.password, pass); +			cmdline_auth_info.got_pass = True; +		} +	} + +	if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server,  +							    &ip, 0, +							    share, "?????",   +							    cmdline_auth_info.username, lp_workgroup(), +							    cmdline_auth_info.password, 0, NULL))) { +		return c; +	} else { +		DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); +		return NULL; +	} +} + +/**************************************************************************** +  main program +****************************************************************************/ + int main(int argc, const char *argv[]) +{ +	char *share; +	int opt; +	int result; +	int todo = 0; +	pstring username_str = {0}; +	pstring path = {0}; +	pstring set_str = {0}; +	enum SMB_QUOTA_TYPE qtype; +	int cmd = 0; +	BOOL test_args = False; +	struct cli_state *cli; +	BOOL fix_user = False; +	SMB_NTQUOTA_STRUCT qt; +	poptContext pc; +	struct poptOption long_options[] = { +		POPT_AUTOHELP +		{ "user", 'u', POPT_ARG_STRING, NULL, 'u', "Show quotas for user", "user" }, +		{ "list", 'L', POPT_ARG_NONE, NULL, 'L', "List user quotas" }, +		{ "fs", 'F', POPT_ARG_NONE, NULL, 'F', "Show filesystem quotas" }, +		{ "set", 'S', POPT_ARG_STRING, NULL, 'S', "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", "SETSTRING" }, +		{ "numeric", 'n', POPT_ARG_NONE, &numeric, True, "Don't resolve sids or limits to names" }, +		{ "verbose", 'v', POPT_ARG_NONE, &verbose, True, "be verbose" }, +		{ "test-args", 't', POPT_ARG_NONE, &test_args, True, "Test arguments"}, +		POPT_COMMON_SAMBA +		POPT_COMMON_CREDENTIALS +		{ NULL } +	}; + +	ZERO_STRUCT(qt); + +	setlinebuf(stdout); + +	dbf = x_stderr; + +	fault_setup(NULL); + +	setup_logging(argv[0],True); + + +	lp_load(dyn_CONFIGFILE,True,False,False); +	load_interfaces(); + +	pc = poptGetContext("smbcquotas", argc, argv, long_options, 0); +	 +	poptSetOtherOptionHelp(pc, "//server1/share1"); + +	while ((opt = poptGetNextOpt(pc)) != -1) { +		switch (opt) { +		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; +		 +		case 'u': +			if (todo != 0) { +				d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); +				exit(EXIT_PARSE_ERROR); +			} +			pstrcpy(username_str,poptGetOptArg(pc)); +			todo = USER_QUOTA; +			fix_user = True; +			break; +		 +		case 'S': +			if (todo != 0) { +				d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); +				exit(EXIT_PARSE_ERROR); +			} +			pstrcpy(set_str,poptGetOptArg(pc)); +			todo = SET_QUOTA; +			break; +		} +	} + +	if (todo == 0) +		todo = USER_QUOTA; + +	if (!fix_user) +		pstrcpy(username_str,cmdline_auth_info.username); + +	/* Make connection to server */ +	if(!poptPeekArg(pc)) {  +		poptPrintUsage(pc, stderr, 0); +		exit(EXIT_PARSE_ERROR); +	} +	 +	pstrcpy(path, poptGetArg(pc)); + +	all_string_sub(path,"/","\\",0); + +	pstrcpy(server,path+2); +	share = strchr_m(server,'\\'); +	if (!share) { +		share = strchr_m(server,'/'); +		if (!share) { +			printf("Invalid argument: %s\n", share); +			exit(EXIT_PARSE_ERROR); +		} +	} + +	*share = 0; +	share++; + +	if (todo == SET_QUOTA) { +		if (parse_quota_set(set_str, username_str, &qtype, &cmd, &qt)) { +			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; +		default:  +			 +			result = EXIT_FAILED; +			break; +	} + +	return result; +} + | 
