smbcquota patch from metze
authorGerald Carter <jerry@samba.org>
Fri, 11 Apr 2003 23:32:00 +0000 (23:32 +0000)
committerGerald Carter <jerry@samba.org>
Fri, 11 Apr 2003 23:32:00 +0000 (23:32 +0000)
(This used to be commit 74fab8f0d24004b1dfd5ce0fd7402895652f941f)

14 files changed:
source3/Makefile.in
source3/include/fake_file.h [new file with mode: 0644]
source3/include/ntquotas.h [new file with mode: 0644]
source3/include/smb.h
source3/include/trans2.h
source3/lib/util_str.c
source3/libsmb/clifile.c
source3/libsmb/clifsinfo.c [new file with mode: 0644]
source3/libsmb/cliquota.c [new file with mode: 0644]
source3/python/py_smb.c
source3/torture/nbio.c
source3/torture/torture.c
source3/torture/utable.c
source3/utils/smbcquotas.c [new file with mode: 0644]

index 641294790d9abacfdd30c4921c1219feacca6112..b7a2519ce72390a420fdd4323d929cbfc820513e 100644 (file)
@@ -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 (file)
index 0000000..3fe6007
--- /dev/null
@@ -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 (file)
index 0000000..1425e59
--- /dev/null
@@ -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 */
index 02b5b9435eeba97897650353723bdbac861dc5a4..62cc95ecb08fd866d3504b19caed69c9849f25e2 100644 (file)
@@ -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
index 3468d3b9950a1647629b4d713fe4ff129bcc84df..2ccf83478be1aba0ed6bd2889cc17aa76cf2fb05 100644 (file)
@@ -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
 
index e2f9f19f581425c41e2af229a2ebd212c07256b4..e561d15f61b64b1d196b8d43790f7509975e005f 100644 (file)
@@ -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
 /**
index 4eb5efe193597cf800ca1f379bd54d3c75ca08a8..b771e135f4e52cc5430fcfeef62acbe27612fa52 100644 (file)
@@ -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 (file)
index 0000000..00fe189
--- /dev/null
@@ -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 (file)
index 0000000..a56a6bd
--- /dev/null
@@ -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&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 {
+                                       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);
+       }       
+}
index 8d81176e4dd3459ba87de413042debd013e4a2d1..d37b73cceb7a3c36109bccaf47f1e6057a6e7eb2 100644 (file)
@@ -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");
index 2d519b40bacefdc57c228865dcfd3e05aed997b0..d8d3ca0c098216de60aebfa1f2f80c4fd7ef8ea2 100644 (file)
@@ -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));
index 5ff7c3bb2d87a4d91c4f6442d7c4d853fad30536..00d5b86ff88167cb3492b0387dbbebfb6d9fa893 100644 (file)
@@ -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;
index 74d5f164c09a2fad26f385d9f4884f2c4122feab..3ec5932b79140f7e897c686caf76f7c63fa83f26 100644 (file)
@@ -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 (file)
index 0000000..c5d0aa8
--- /dev/null
@@ -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, &quota_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;
+}
+