The Samba-Bugzilla – Attachment 8592 Details for
Bug 9690
[PATCH] libsmbclient: Add SMBC_open2_ctx to support share_access flags
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
[PATCH] libsmbclient: Add SMBC_open2_ctx to support share_access flags
0001-libsmbclient-Add-SMBC_open2_ctx-to-support-share_acc.patch (text/plain), 14.49 KB, created by
SATOH Fumiyasu
on 2013-02-27 14:21:05 UTC
(
hide
)
Description:
[PATCH] libsmbclient: Add SMBC_open2_ctx to support share_access flags
Filename:
MIME Type:
Creator:
SATOH Fumiyasu
Created:
2013-02-27 14:21:05 UTC
Size:
14.49 KB
patch
obsolete
>From 3592ccb9bc5343feb82304f999bee8a7589b7c3b Mon Sep 17 00:00:00 2001 >From: SATOH Fumiyasu <fumiyas@osstech.co.jp> >Date: Wed, 27 Feb 2013 02:51:08 +0900 >Subject: [PATCH] libsmbclient: Add SMBC_open2_ctx to support share_access > flags > >--- > source3/include/libsmb_internal.h | 13 ++ > source3/include/libsmbclient.h | 26 ++++ > source3/libsmb/libsmb_compat.c | 42 +++++++ > source3/libsmb/libsmb_context.c | 2 + > source3/libsmb/libsmb_file.c | 237 +++++++++++++++++++++++++++++++++++++ > source3/libsmb/libsmb_setget.c | 24 ++++ > 6 files changed, 344 insertions(+) > >diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h >index 61dc95e..dac44a8 100644 >--- a/source3/include/libsmb_internal.h >+++ b/source3/include/libsmb_internal.h >@@ -347,6 +347,19 @@ SMBC_creat_ctx(SMBCCTX *context, > const char *path, > mode_t mode); > >+SMBCFILE * >+SMBC_open2_ctx(SMBCCTX *context, >+ const char *fname, >+ int flags, >+ mode_t mode, >+ unsigned long share_access); >+ >+SMBCFILE * >+SMBC_creat2_ctx(SMBCCTX *context, >+ const char *path, >+ mode_t mode, >+ unsigned long share_access); >+ > ssize_t > SMBC_read_ctx(SMBCCTX *context, > SMBCFILE *file, >diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h >index ccf80da..135ba9b 100644 >--- a/source3/include/libsmbclient.h >+++ b/source3/include/libsmbclient.h >@@ -162,6 +162,11 @@ typedef enum smbc_share_mode > SMBC_SHAREMODE_DENY_FCB = 7 > } smbc_share_mode; > >+/* Values for the option "share_access" of smbc_open2_fn and smbc_creat2_fn */ >+#define SMBC_SHAREACCESS_NONE 0 /* Cannot be used in bitmask. */ >+#define SMBC_SHAREACCESS_READ 1 >+#define SMBC_SHAREACCESS_WRITE 2 >+#define SMBC_SHAREACCESS_DELETE 4 > > /** > * Values for option SMB Encryption Level, as set and retrieved with >@@ -836,6 +841,21 @@ typedef SMBCFILE * (*smbc_creat_fn)(SMBCCTX *c, > smbc_creat_fn smbc_getFunctionCreat(SMBCCTX *c); > void smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn); > >+typedef SMBCFILE * (*smbc_open2_fn)(SMBCCTX *c, >+ const char *fname, >+ int flags, >+ mode_t mode, >+ unsigned long share_access); >+smbc_open2_fn smbc_getFunctionOpen2(SMBCCTX *c); >+void smbc_setFunctionOpen2(SMBCCTX *c, smbc_open2_fn fn); >+ >+typedef SMBCFILE * (*smbc_creat2_fn)(SMBCCTX *c, >+ const char *path, >+ mode_t mode, >+ unsigned long share_access); >+smbc_creat2_fn smbc_getFunctionCreat2(SMBCCTX *c); >+void smbc_setFunctionCreat2(SMBCCTX *c, smbc_creat2_fn); >+ > typedef ssize_t (*smbc_read_fn)(SMBCCTX *c, > SMBCFILE *file, > void *buf, >@@ -1224,6 +1244,8 @@ SMBCCTX * smbc_set_context(SMBCCTX * new_context); > > int smbc_open(const char *furl, int flags, mode_t mode); > >+int smbc_open2(const char *furl, int flags, mode_t mode, unsigned long share_access); >+ > /**@ingroup file > * Create a file on an SMB server. > * >@@ -1258,6 +1280,8 @@ int smbc_open(const char *furl, int flags, mode_t mode); > > int smbc_creat(const char *furl, mode_t mode); > >+int smbc_creat2(const char *furl, mode_t mode, unsigned long share_access); >+ > /**@ingroup file > * Read from a file using an opened file handle. > * >@@ -2891,6 +2915,8 @@ struct _SMBCCTX > */ > smbc_open_fn open DEPRECATED_SMBC_INTERFACE; > smbc_creat_fn creat DEPRECATED_SMBC_INTERFACE; >+ smbc_open2_fn open2 DEPRECATED_SMBC_INTERFACE; >+ smbc_creat2_fn creat2 DEPRECATED_SMBC_INTERFACE; > smbc_read_fn read DEPRECATED_SMBC_INTERFACE; > smbc_write_fn write DEPRECATED_SMBC_INTERFACE; > smbc_unlink_fn unlink DEPRECATED_SMBC_INTERFACE; >diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c >index 5b2ef2d..ae2d6ed 100644 >--- a/source3/libsmb/libsmb_compat.c >+++ b/source3/libsmb/libsmb_compat.c >@@ -195,6 +195,48 @@ smbc_creat(const char *furl, > } > > >+int >+smbc_open2(const char *furl, >+ int flags, >+ mode_t mode, >+ unsigned long share_access) >+{ >+ SMBCFILE * file; >+ int fd; >+ >+ file = smbc_getFunctionOpen2(statcont)(statcont, furl, flags, mode, share_access); >+ if (!file) >+ return -1; >+ >+ fd = add_fd(file); >+ if (fd == -1) >+ smbc_getFunctionClose(statcont)(statcont, file); >+ return fd; >+} >+ >+ >+int >+smbc_creat2(const char *furl, >+ mode_t mode, >+ unsigned long share_access) >+{ >+ SMBCFILE * file; >+ int fd; >+ >+ file = smbc_getFunctionCreat2(statcont)(statcont, furl, mode, share_access); >+ if (!file) >+ return -1; >+ >+ fd = add_fd(file); >+ if (fd == -1) { >+ /* Hmm... should we delete the file too ? I guess we could try */ >+ smbc_getFunctionClose(statcont)(statcont, file); >+ smbc_getFunctionUnlink(statcont)(statcont, furl); >+ } >+ return fd; >+} >+ >+ > ssize_t > smbc_read(int fd, > void *buf, >diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c >index c9ca455..76ce080 100644 >--- a/source3/libsmb/libsmb_context.c >+++ b/source3/libsmb/libsmb_context.c >@@ -191,6 +191,8 @@ smbc_new_context(void) > > smbc_setFunctionOpen(context, SMBC_open_ctx); > smbc_setFunctionCreat(context, SMBC_creat_ctx); >+ smbc_setFunctionOpen2(context, SMBC_open2_ctx); >+ smbc_setFunctionCreat2(context, SMBC_creat2_ctx); > smbc_setFunctionRead(context, SMBC_read_ctx); > smbc_setFunctionWrite(context, SMBC_write_ctx); > smbc_setFunctionClose(context, SMBC_close_ctx); >diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c >index fde7122..2237703 100644 >--- a/source3/libsmb/libsmb_file.c >+++ b/source3/libsmb/libsmb_file.c >@@ -27,6 +27,45 @@ > #include "libsmbclient.h" > #include "libsmb_internal.h" > >+static int unix_o_flags2nt_flags(int flags, >+ uint32_t *desired_access, >+ uint32_t *create_disposition) >+{ >+ int rw_flags = flags & (O_RDONLY | O_WRONLY | O_RDWR); >+ >+ if (rw_flags == O_RDONLY) { >+ *desired_access = SEC_FILE_READ_DATA; >+ } else if (rw_flags == O_WRONLY) { >+ *desired_access = SEC_FILE_WRITE_DATA; >+ } else if (rw_flags == O_RDWR) { >+ *desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA; >+ } else { >+ return -1; >+ } >+ if (flags & O_APPEND) { >+ *desired_access |= SEC_FILE_APPEND_DATA; >+ } >+ >+ if (flags & O_TRUNC) { >+ if (flags & O_CREAT) { >+ *create_disposition = FILE_OVERWRITE_IF; >+ } else { >+ *create_disposition = FILE_OVERWRITE; >+ } >+ } else { >+ if (flags & O_CREAT) { >+ if (flags & O_EXCL) { >+ *create_disposition = FILE_CREATE; >+ } else { >+ *create_disposition = FILE_OPEN_IF; >+ } >+ } else { >+ *create_disposition = FILE_OPEN; >+ } >+ } >+ >+ return 0; >+} > > /* > * Routine to open() a file ... >@@ -196,6 +235,189 @@ SMBC_open_ctx(SMBCCTX *context, > return NULL; > } > >+SMBCFILE * >+SMBC_open2_ctx(SMBCCTX *context, >+ const char *fname, >+ int flags, >+ mode_t mode, >+ unsigned long share_access) >+{ >+ char *server = NULL; >+ char *share = NULL; >+ char *user = NULL; >+ char *password = NULL; >+ char *workgroup = NULL; >+ char *path = NULL; >+ char *targetpath = NULL; >+ struct cli_state *targetcli = NULL; >+ SMBCSRV *srv = NULL; >+ SMBCFILE *file = NULL; >+ uint16_t fd; >+ NTSTATUS status = NT_STATUS_OBJECT_PATH_INVALID; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ >+ if (!context || !context->internal->initialized) { >+ errno = EINVAL; /* Best I can think of ... */ >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ >+ if (!fname) { >+ errno = EINVAL; >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ >+ if (SMBC_parse_path(frame, >+ context, >+ fname, >+ &workgroup, >+ &server, >+ &share, >+ &path, >+ &user, >+ &password, >+ NULL)) { >+ errno = EINVAL; >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ >+ if (!user || user[0] == (char)0) { >+ user = talloc_strdup(frame, smbc_getUser(context)); >+ if (!user) { >+ errno = ENOMEM; >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ } >+ >+ srv = SMBC_server(frame, context, True, >+ server, share, &workgroup, &user, &password); >+ if (!srv) { >+ if (errno == EPERM) errno = EACCES; >+ TALLOC_FREE(frame); >+ return NULL; /* SMBC_server sets errno */ >+ } >+ >+ /* Hmmm, the test for a directory is suspect here ... FIXME */ >+ >+ if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { >+ status = NT_STATUS_OBJECT_PATH_INVALID; >+ } else { >+ uint32_t desired_access; >+ uint32_t create_disposition; >+ >+ file = SMB_MALLOC_P(SMBCFILE); >+ if (!file) { >+ errno = ENOMEM; >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ >+ ZERO_STRUCTP(file); >+ >+ /*d_printf(">>>open: resolving %s\n", path);*/ >+ if (!cli_resolve_path(frame, "", context->internal->auth_info, >+ srv->cli, path, >+ &targetcli, &targetpath)) { >+ DEBUG(0, ("Could not resolve %s\n", path)); >+ errno = ENOENT; >+ SAFE_FREE(file); >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ >+ >+ if (unix_o_flags2nt_flags(flags, &desired_access, >+ &create_disposition) == -1) { >+ SAFE_FREE(file); >+ TALLOC_FREE(frame); >+ errno = EINVAL; >+ return NULL; >+ } >+ >+ status = cli_ntcreate(targetcli, targetpath, >+ 0, /* create_flags */ >+ desired_access, >+ 0, /* file_attrs */ >+ share_access, >+ create_disposition, >+ 0, /* create_options */ >+ 0, /* security_flags */ >+ &fd); >+ if (!NT_STATUS_IS_OK(status)) { >+ >+ /* Handle the error ... */ >+ >+ SAFE_FREE(file); >+ errno = SMBC_errno(context, targetcli); >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ >+ /* Fill in file struct */ >+ >+ file->cli_fd = fd; >+ file->fname = SMB_STRDUP(fname); >+ file->srv = srv; >+ file->offset = 0; >+ file->file = True; >+ >+ DLIST_ADD(context->internal->files, file); >+ >+ /* >+ * If the file was opened in O_APPEND mode, all write >+ * operations should be appended to the file. To do that, >+ * though, using this protocol, would require a getattrE() >+ * call for each and every write, to determine where the end >+ * of the file is. (There does not appear to be an append flag >+ * in the protocol.) Rather than add all of that overhead of >+ * retrieving the current end-of-file offset prior to each >+ * write operation, we'll assume that most append operations >+ * will continuously write, so we'll just set the offset to >+ * the end of the file now and hope that's adequate. >+ * >+ * Note to self: If this proves inadequate, and O_APPEND >+ * should, in some cases, be forced for each write, add a >+ * field in the context options structure, for >+ * "strict_append_mode" which would select between the current >+ * behavior (if FALSE) or issuing a getattrE() prior to each >+ * write and forcing the write to the end of the file (if >+ * TRUE). Adding that capability will likely require adding >+ * an "append" flag into the _SMBCFILE structure to track >+ * whether a file was opened in O_APPEND mode. -- djl >+ */ >+ if (flags & O_APPEND) { >+ if (SMBC_lseek_ctx(context, file, 0, SEEK_END) < 0) { >+ (void) SMBC_close_ctx(context, file); >+ errno = ENXIO; >+ TALLOC_FREE(frame); >+ return NULL; >+ } >+ } >+ >+ TALLOC_FREE(frame); >+ return file; >+ } >+ >+ /* Check if opendir needed ... */ >+ >+ if (!NT_STATUS_IS_OK(status)) { >+ int eno = 0; >+ >+ eno = SMBC_errno(context, srv->cli); >+ file = smbc_getFunctionOpendir(context)(context, fname); >+ if (!file) errno = eno; >+ TALLOC_FREE(frame); >+ return file; >+ } >+ >+ errno = EINVAL; /* FIXME, correct errno ? */ >+ TALLOC_FREE(frame); >+ return NULL; >+} >+ > /* > * Routine to create a file > */ >@@ -214,6 +436,21 @@ SMBC_creat_ctx(SMBCCTX *context, > O_WRONLY | O_CREAT | O_TRUNC, mode); > } > >+SMBCFILE * >+SMBC_creat2_ctx(SMBCCTX *context, >+ const char *path, >+ mode_t mode, >+ unsigned long share_access) >+{ >+ if (!context || !context->internal->initialized) { >+ errno = EINVAL; >+ return NULL; >+ } >+ >+ return SMBC_open2_ctx(context, path, >+ O_WRONLY | O_CREAT | O_TRUNC, mode, share_access); >+} >+ > /* > * Routine to read() a file ... > */ >diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c >index 0a02346..e8348d1 100644 >--- a/source3/libsmb/libsmb_setget.c >+++ b/source3/libsmb/libsmb_setget.c >@@ -621,6 +621,30 @@ smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn) > c->creat = fn; > } > >+smbc_open2_fn >+smbc_getFunctionOpen2(SMBCCTX *c) >+{ >+ return c->open2; >+} >+ >+void >+smbc_setFunctionOpen2(SMBCCTX *c, smbc_open2_fn fn) >+{ >+ c->open2 = fn; >+} >+ >+smbc_creat2_fn >+smbc_getFunctionCreat2(SMBCCTX *c) >+{ >+ return c->creat2; >+} >+ >+void >+smbc_setFunctionCreat2(SMBCCTX *c, smbc_creat2_fn fn) >+{ >+ c->creat2 = fn; >+} >+ > smbc_read_fn > smbc_getFunctionRead(SMBCCTX *c) > { >-- >1.7.10.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 9690
: 8592