diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libsmb/libsmb_cache.c | 55 | ||||
-rw-r--r-- | source3/libsmb/libsmb_compat.c | 57 | ||||
-rw-r--r-- | source3/libsmb/libsmb_file.c | 224 | ||||
-rw-r--r-- | source3/libsmb/libsmb_misc.c | 18 | ||||
-rw-r--r-- | source3/libsmb/libsmb_path.c | 88 | ||||
-rw-r--r-- | source3/libsmb/libsmb_printjob.c | 100 | ||||
-rw-r--r-- | source3/libsmb/libsmb_setget.c | 6 | ||||
-rw-r--r-- | source3/libsmb/libsmb_stat.c | 79 | ||||
-rw-r--r-- | source3/libsmb/libsmb_xattr.c | 409 |
9 files changed, 468 insertions, 568 deletions
diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index bfacea368d..53cd3d5a77 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -5,17 +5,17 @@ Copyright (C) Richard Sharpe 2000 Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -34,7 +34,7 @@ struct smbc_server_cache { char *workgroup; char *username; SMBCSRV *server; - + struct smbc_server_cache *next, *prev; }; @@ -53,51 +53,51 @@ SMBC_add_cached_server(SMBCCTX * context, const char * username) { struct smbc_server_cache * srvcache = NULL; - + if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) { errno = ENOMEM; DEBUG(3, ("Not enough space for server cache allocation\n")); return 1; } - + ZERO_STRUCTP(srvcache); - + srvcache->server = newsrv; - + srvcache->server_name = SMB_STRDUP(server); if (!srvcache->server_name) { errno = ENOMEM; goto failed; } - + srvcache->share_name = SMB_STRDUP(share); if (!srvcache->share_name) { errno = ENOMEM; goto failed; } - + srvcache->workgroup = SMB_STRDUP(workgroup); if (!srvcache->workgroup) { errno = ENOMEM; goto failed; } - + srvcache->username = SMB_STRDUP(username); if (!srvcache->username) { errno = ENOMEM; goto failed; } - + DLIST_ADD(context->internal->server_cache, srvcache); return 0; - + failed: SAFE_FREE(srvcache->server_name); SAFE_FREE(srvcache->share_name); SAFE_FREE(srvcache->workgroup); SAFE_FREE(srvcache->username); SAFE_FREE(srvcache); - + return 1; } @@ -116,19 +116,19 @@ SMBC_get_cached_server(SMBCCTX * context, const char * user) { struct smbc_server_cache * srv = NULL; - + /* Search the cache lines */ for (srv = context->internal->server_cache; srv; srv = srv->next) { - + if (strcmp(server,srv->server_name) == 0 && strcmp(workgroup,srv->workgroup) == 0 && strcmp(user, srv->username) == 0) { - + /* If the share name matches, we're cool */ if (strcmp(share, srv->share_name) == 0) { return srv->server; } - + /* * We only return an empty share name or the attribute * server on an exact match (which would have been @@ -136,7 +136,7 @@ SMBC_get_cached_server(SMBCCTX * context, */ if (*share == '\0' || strcmp(share, "*IPC$") == 0) continue; - + /* * Never return an empty share name or the attribute * server if it wasn't what was requested. @@ -144,7 +144,7 @@ SMBC_get_cached_server(SMBCCTX * context, if (*srv->share_name == '\0' || strcmp(srv->share_name, "*IPC$") == 0) continue; - + /* * If we're only allowing one share per server, then * a connection to the server (other than the @@ -163,7 +163,7 @@ SMBC_get_cached_server(SMBCCTX * context, smbc_getFunctionRemoveCachedServer(context)(context, srv->server); continue; } - + /* * Save the new share name. We've * disconnected from the old share, and are @@ -178,13 +178,12 @@ SMBC_get_cached_server(SMBCCTX * context, smbc_getFunctionRemoveCachedServer(context)(context, srv->server); continue; } - - + return srv->server; } } } - + return NULL; } @@ -199,10 +198,10 @@ SMBC_remove_cached_server(SMBCCTX * context, SMBCSRV * server) { struct smbc_server_cache * srv = NULL; - + for (srv = context->internal->server_cache; srv; srv = srv->next) { if (server == srv->server) { - + /* remove this sucker */ DLIST_REMOVE(context->internal->server_cache, srv); SAFE_FREE(srv->server_name); @@ -228,13 +227,13 @@ SMBC_purge_cached_servers(SMBCCTX * context) struct smbc_server_cache * srv; struct smbc_server_cache * next; int could_not_purge_all = 0; - + for (srv = context->internal->server_cache, next = (srv ? srv->next :NULL); srv; srv = next, next = (srv ? srv->next : NULL)) { - + if (SMBC_remove_unused_server(context, srv->server)) { /* could not be removed */ could_not_purge_all = 1; diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 56d113f31a..5b2ef2d6f8 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -6,17 +6,17 @@ Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -55,11 +55,10 @@ static int add_fd(SMBCFILE * file) { struct smbc_compat_fdlist * f = smbc_compat_fd_avail; - + if (f) { /* We found one that's available */ DLIST_REMOVE(smbc_compat_fd_avail, f); - } else { /* * None were available, so allocate one. Keep the number of @@ -72,19 +71,19 @@ add_fd(SMBCFILE * file) errno = EMFILE; return -1; } - + f = SMB_MALLOC_P(struct smbc_compat_fdlist); if (!f) { errno = ENOMEM; return -1; } - + f->fd = SMBC_BASE_FD + smbc_compat_nextfd++; } - + f->file = file; DLIST_ADD(smbc_compat_fd_in_use, f); - + return f->fd; } @@ -95,13 +94,13 @@ static int del_fd(int fd) { struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; - + while (f) { if (f->fd == fd) break; f = f->next; } - + if (f) { /* found */ DLIST_REMOVE(smbc_compat_fd_in_use, f); @@ -122,17 +121,17 @@ smbc_init(smbc_get_auth_data_fn fn, statcont = smbc_new_context(); if (!statcont) return -1; - + smbc_setDebug(statcont, debug); smbc_setFunctionAuthData(statcont, fn); - + if (!smbc_init_context(statcont)) { smbc_free_context(statcont, False); return -1; } - + smbc_compat_initialized = 1; - + return 0; } return 0; @@ -143,15 +142,15 @@ SMBCCTX * smbc_set_context(SMBCCTX * context) { SMBCCTX *old_context = statcont; - + if (context) { /* Save provided context. It must have been initialized! */ statcont = context; - + /* You'd better know what you're doing. We won't help you. */ smbc_compat_initialized = 1; } - + return old_context; } @@ -163,11 +162,11 @@ smbc_open(const char *furl, { SMBCFILE * file; int fd; - + file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) smbc_getFunctionClose(statcont)(statcont, file); @@ -181,11 +180,11 @@ smbc_creat(const char *furl, { SMBCFILE * file; int fd; - + file = smbc_getFunctionCreat(statcont)(statcont, furl, mode); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) { /* Hmm... should we delete the file too ? I guess we could try */ @@ -250,15 +249,15 @@ smbc_opendir(const char *durl) { SMBCFILE * file; int fd; - + file = smbc_getFunctionOpendir(statcont)(statcont, durl); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) smbc_getFunctionClosedir(statcont)(statcont, file); - + return fd; } @@ -372,14 +371,14 @@ smbc_utime(const char *fname, struct utimbuf *utbuf) { struct timeval tv[2]; - + if (utbuf == NULL) return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL); - + tv[0].tv_sec = utbuf->actime; tv[1].tv_sec = utbuf->modtime; tv[0].tv_usec = tv[1].tv_usec = 0; - + return smbc_getFunctionUtimes(statcont)(statcont, fname, tv); } #endif @@ -534,7 +533,7 @@ int smbc_open_print_job(const char *fname) { SMBCFILE * file; - + file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname); if (!file) return -1; return file->cli_fd; diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index f6cd8ec03f..b3b0bc2b9f 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -50,23 +50,19 @@ SMBC_open_ctx(SMBCCTX *context, 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, @@ -81,7 +77,7 @@ SMBC_open_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -90,31 +86,29 @@ SMBC_open_ctx(SMBCCTX *context, 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 { 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, @@ -126,30 +120,29 @@ SMBC_open_ctx(SMBCCTX *context, return NULL; } /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ - + status = cli_open(targetcli, targetpath, flags, context->internal->share_mode, &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, @@ -180,29 +173,26 @@ SMBC_open_ctx(SMBCCTX *context, 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; - } /* @@ -214,14 +204,11 @@ SMBC_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - if (!context || !context->internal->initialized) { - errno = EINVAL; return NULL; - } - + return SMBC_open_ctx(context, path, O_WRONLY | O_CREAT | O_TRUNC, mode); } @@ -242,7 +229,7 @@ SMBC_read_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + /* * offset: * @@ -253,35 +240,31 @@ SMBC_read_ctx(SMBCCTX *context, * retrieving data at an offset greater than 4GB. */ off_t offset; - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; - } - + offset = file->offset; - + /* Check that the buffer exists ... */ - + if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + /*d_printf(">>>read: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, @@ -297,7 +280,7 @@ SMBC_read_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>read: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", context->internal->auth_info, file->srv->cli, path, @@ -308,24 +291,21 @@ SMBC_read_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); - + if (ret < 0) { - errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - } - + file->offset += ret; - + DEBUG(4, (" --> %d\n", ret)); - + TALLOC_FREE(frame); return ret; /* Success, ret bytes of data ... */ - } /* @@ -345,34 +325,31 @@ SMBC_write_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + /* First check all pointers before dereferencing them */ - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + /* Check that the buffer exists ... */ - + if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ - + /*d_printf(">>>write: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, @@ -399,19 +376,17 @@ SMBC_write_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - + ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); - if (ret <= 0) { errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - } - + file->offset += ret; - + TALLOC_FREE(frame); return ret; /* Success, 0 bytes of data ... */ } @@ -430,26 +405,25 @@ SMBC_close_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + /* IS a dir ... */ if (!file->file) { TALLOC_FREE(frame); return smbc_getFunctionClosedir(context)(context, file); } - + /*d_printf(">>>close: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, @@ -465,7 +439,7 @@ SMBC_close_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>close: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", context->internal->auth_info, file->srv->cli, path, @@ -476,9 +450,8 @@ SMBC_close_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ - + if (!NT_STATUS_IS_OK(cli_close(targetcli, file->cli_fd))) { - DEBUG(3, ("cli_close failed on %s. purging server.\n", file->fname)); /* Deallocate slot and remove the server @@ -491,14 +464,12 @@ SMBC_close_ctx(SMBCCTX *context, smbc_getFunctionRemoveUnusedServer(context)(context, srv); TALLOC_FREE(frame); return -1; - } - + DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); TALLOC_FREE(frame); - return 0; } @@ -523,14 +494,13 @@ SMBC_getatr(SMBCCTX * context, struct cli_state *targetcli = NULL; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return False; } - + /* path fixup for . and .. */ if (strequal(path, ".") || strequal(path, "..")) { fixedpath = talloc_strdup(frame, "\\"); @@ -550,7 +520,7 @@ SMBC_getatr(SMBCCTX * context, trim_string(fixedpath, NULL, "\\."); } DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); - + if (!cli_resolve_path(frame, "", context->internal->auth_info, srv->cli, fixedpath, &targetcli, &targetpath)) { @@ -559,7 +529,7 @@ SMBC_getatr(SMBCCTX * context, TALLOC_FREE(frame); return False; } - + if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, create_time_ts, @@ -570,45 +540,38 @@ SMBC_getatr(SMBCCTX * context, TALLOC_FREE(frame); return True; } - + /* if this is NT then don't bother with the getatr */ if (targetcli->capabilities & CAP_NT_SMBS) { errno = EPERM; TALLOC_FREE(frame); return False; } - + if (NT_STATUS_IS_OK(cli_getatr(targetcli, targetpath, mode, size, &write_time))) { - struct timespec w_time_ts; - + w_time_ts = convert_time_t_to_timespec(write_time); - if (write_time_ts != NULL) { *write_time_ts = w_time_ts; } - if (create_time_ts != NULL) { *create_time_ts = w_time_ts; } - if (access_time_ts != NULL) { *access_time_ts = w_time_ts; } - if (change_time_ts != NULL) { *change_time_ts = w_time_ts; } - srv->no_pathinfo2 = True; TALLOC_FREE(frame); return True; } - + errno = EPERM; TALLOC_FREE(frame); return False; - } /* @@ -632,7 +595,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, uint16_t fd; int ret; TALLOC_CTX *frame = talloc_stackframe(); - + /* * First, try setpathinfo (if qpathinfo succeeded), for it is the * modern function for "new code" to be using, and it works given a @@ -646,7 +609,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, write_time, change_time, mode)) { - + /* * setpathinfo is not supported; go to plan B. * @@ -656,27 +619,26 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * cli_setattrE() which should work on all OS versions, and * supports both times. */ - + /* Don't try {q,set}pathinfo() again, with this server */ srv->no_pathinfo = True; - + /* Open the file */ if (!NT_STATUS_IS_OK(cli_open(srv->cli, path, O_RDWR, DENY_NONE, &fd))) { - errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } - + /* Set the new attributes */ ret = NT_STATUS_IS_OK(cli_setattrE(srv->cli, fd, change_time, access_time, write_time)); - + /* Close the file */ cli_close(srv->cli, fd); - + /* * Unfortunately, setattrE() doesn't have a provision for * setting the access mode (attributes). We'll have to try @@ -686,14 +648,14 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, if (ret && mode != (uint16) -1) { ret = NT_STATUS_IS_OK(cli_setatr(srv->cli, path, mode, 0)); } - + if (! ret) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return False; } } - + TALLOC_FREE(frame); return True; } @@ -714,39 +676,32 @@ SMBC_lseek_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { - errno = EBADF; TALLOC_FREE(frame); return -1; - } - + if (!file->file) { - errno = EINVAL; TALLOC_FREE(frame); return -1; /* Can't lseek a dir ... */ - } - + switch (whence) { case SEEK_SET: file->offset = offset; break; - case SEEK_CUR: file->offset += offset; break; - case SEEK_END: /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, @@ -763,7 +718,7 @@ SMBC_lseek_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>lseek: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", context->internal->auth_info, file->srv->cli, path, @@ -773,8 +728,8 @@ SMBC_lseek_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } + /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ - if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL)) { @@ -789,16 +744,13 @@ SMBC_lseek_ctx(SMBCCTX *context, } file->offset = size + offset; break; - default: errno = EINVAL; break; - } - + TALLOC_FREE(frame); return file->offset; - } @@ -820,26 +772,25 @@ SMBC_ftruncate_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + if (!file->file) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, @@ -855,7 +806,7 @@ SMBC_ftruncate_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", context->internal->auth_info, file->srv->cli, path, @@ -866,14 +817,13 @@ SMBC_ftruncate_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + if (!NT_STATUS_IS_OK(cli_ftruncate(targetcli, file->cli_fd, (uint64_t)size))) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + TALLOC_FREE(frame); return 0; - } diff --git a/source3/libsmb/libsmb_misc.c b/source3/libsmb/libsmb_misc.c index dd7add5a61..a6e96350f5 100644 --- a/source3/libsmb/libsmb_misc.c +++ b/source3/libsmb/libsmb_misc.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -50,24 +50,24 @@ SMBC_errno(SMBCCTX *context, struct cli_state *c) { int ret = cli_errno(c); - + if (cli_is_dos_error(c)) { uint8 eclass; uint32 ecode; - + cli_dos_error(c, &eclass, &ecode); - + DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", (int)eclass, (int)ecode, (int)ecode, ret)); } else { NTSTATUS status; - + status = cli_nt_error(c); - + DEBUG(3,("smbc errno %s -> %d\n", nt_errstr(status), ret)); } - + return ret; } diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 6a59a12ed0..9d2eafc8d7 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -60,19 +60,19 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) int err_count = 0; size_t newlen = 1; char *p, *dest; - + if (old_length == 0) { return 0; } - + *pp_dest = NULL; for (i = 0; i < old_length; ) { unsigned char character = src[i++]; - + if (character == '%') { int a = i+1 < old_length ? hex2int(src[i]) : -1; int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - + /* Replace valid sequence */ if (a != -1 && b != -1) { /* Replace valid %xx sequence with %dd */ @@ -87,20 +87,20 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) } newlen++; } - + dest = TALLOC_ARRAY(ctx, char, newlen); if (!dest) { return err_count; } - + err_count = 0; for (p = dest, i = 0; i < old_length; ) { unsigned char character = src[i++]; - + if (character == '%') { int a = i+1 < old_length ? hex2int(src[i]) : -1; int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - + /* Replace valid sequence */ if (a != -1 && b != -1) { /* Replace valid %xx sequence with %dd */ @@ -115,7 +115,7 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) } *p++ = character; } - + *p = '\0'; *pp_dest = dest; return err_count; @@ -129,7 +129,7 @@ smbc_urldecode(char *dest, TALLOC_CTX *frame = talloc_stackframe(); char *pdest; int ret = urldecode_talloc(frame, &pdest, src); - + if (pdest) { strlcpy(dest, pdest, max_dest_len); } @@ -151,9 +151,9 @@ smbc_urlencode(char *dest, int max_dest_len) { char hex[] = "0123456789ABCDEF"; - + for (; *src != '\0' && max_dest_len >= 3; src++) { - + if ((*src < '0' && *src != '-' && *src != '.') || @@ -172,10 +172,10 @@ smbc_urlencode(char *dest, max_dest_len--; } } - + *dest++ = '\0'; max_dest_len--; - + return max_dest_len; } @@ -235,19 +235,19 @@ SMBC_parse_path(TALLOC_CTX *ctx, char *q, *r; char *workgroup = NULL; int len; - + /* Ensure these returns are at least valid pointers. */ *pp_server = talloc_strdup(ctx, ""); *pp_share = talloc_strdup(ctx, ""); *pp_path = talloc_strdup(ctx, ""); *pp_user = talloc_strdup(ctx, ""); *pp_password = talloc_strdup(ctx, ""); - + if (!*pp_server || !*pp_share || !*pp_path || !*pp_user || !*pp_password) { return -1; } - + /* * Assume we wont find an authentication domain to parse, so default * to the workgroup in the provided context. @@ -256,54 +256,54 @@ SMBC_parse_path(TALLOC_CTX *ctx, *pp_workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context)); } - + if (pp_options) { *pp_options = talloc_strdup(ctx, ""); } s = talloc_strdup(ctx, fname); - + /* see if it has the right prefix */ len = strlen(SMBC_PREFIX); if (strncmp(s,SMBC_PREFIX,len) || (s[len] != '/' && s[len] != 0)) { return -1; /* What about no smb: ? */ } - + p = s + len; - + /* Watch the test below, we are testing to see if we should exit */ - + if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { DEBUG(1, ("Invalid path (does not begin with smb://")); return -1; } - + p += 2; /* Skip the double slash */ - + /* See if any options were specified */ if ((q = strrchr(p, '?')) != NULL ) { /* There are options. Null terminate here and point to them */ *q++ = '\0'; - + DEBUG(4, ("Found options '%s'", q)); - + /* Copy the options */ if (pp_options && *pp_options != NULL) { TALLOC_FREE(*pp_options); *pp_options = talloc_strdup(ctx, q); } } - + if (*p == '\0') { goto decoding; } - + if (*p == '/') { int wl = strlen(smbc_getWorkgroup(context)); - + if (wl > 16) { wl = 16; } - + *pp_server = talloc_strdup(ctx, smbc_getWorkgroup(context)); if (!*pp_server) { return -1; @@ -311,27 +311,27 @@ SMBC_parse_path(TALLOC_CTX *ctx, *pp_server[wl] = '\0'; return 0; } - + /* * ok, its for us. Now parse out the server, share etc. * * However, we want to parse out [[domain;]user[:password]@] if it * exists ... */ - + /* check that '@' occurs before '/', if '/' exists at all */ q = strchr_m(p, '@'); r = strchr_m(p, '/'); if (q && (!r || q < r)) { char *userinfo = NULL; const char *u; - + next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); if (!userinfo) { return -1; } u = userinfo; - + if (strchr_m(u, ';')) { next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); if (!workgroup) { @@ -341,7 +341,7 @@ SMBC_parse_path(TALLOC_CTX *ctx, *pp_workgroup = workgroup; } } - + if (strchr_m(u, ':')) { next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); if (!*pp_user) { @@ -358,19 +358,19 @@ SMBC_parse_path(TALLOC_CTX *ctx, } } } - + if (!next_token_talloc(ctx, &p, pp_server, "/")) { return -1; } - + if (*p == (char)0) { goto decoding; /* That's it ... */ } - + if (!next_token_talloc(ctx, &p, pp_share, "/")) { return -1; } - + /* * Prepend a leading slash if there's a file path, as required by * NetApp filers. @@ -386,9 +386,8 @@ SMBC_parse_path(TALLOC_CTX *ctx, return -1; } string_replace(*pp_path, '/', '\\'); - + decoding: - (void) urldecode_talloc(ctx, pp_path, *pp_path); (void) urldecode_talloc(ctx, pp_server, *pp_server); (void) urldecode_talloc(ctx, pp_share, *pp_share); @@ -407,7 +406,6 @@ decoding: workgroup, *pp_user, *pp_password); - return 0; } diff --git a/source3/libsmb/libsmb_printjob.c b/source3/libsmb/libsmb_printjob.c index c8d7ad039d..ea0cb37a14 100644 --- a/source3/libsmb/libsmb_printjob.c +++ b/source3/libsmb/libsmb_printjob.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -41,22 +41,21 @@ SMBC_open_print_job_ctx(SMBCCTX *context, char *password = NULL; char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return NULL; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return NULL; } - + DEBUG(4, ("SMBC_open_print_job_ctx(%s)\n", fname)); - + if (SMBC_parse_path(frame, context, fname, @@ -71,9 +70,9 @@ SMBC_open_print_job_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + /* What if the path is empty, or the file exists? */ - + TALLOC_FREE(frame); return smbc_getFunctionOpen(context)(context, fname, O_WRONLY, 666); } @@ -98,79 +97,66 @@ SMBC_print_file_ctx(SMBCCTX *c_file, int tot_bytes = 0; char buf[4096]; TALLOC_CTX *frame = talloc_stackframe(); - + if (!c_file || !c_file->internal->initialized || !c_print || !c_print->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + if (!fname && !printq) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + /* Try to open the file for reading ... */ - + if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname, O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); TALLOC_FREE(frame); return -1; /* smbc_open sets errno */ } - + /* Now, try to open the printer file for writing */ - + if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, printq)) < 0) { - saverr = errno; /* Save errno */ smbc_getFunctionClose(c_file)(c_file, fid1); errno = saverr; TALLOC_FREE(frame); return -1; - } - + while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1, buf, sizeof(buf))) > 0) { - tot_bytes += bytes; - + if ((smbc_getFunctionWrite(c_print)(c_print, fid2, buf, bytes)) < 0) { - saverr = errno; smbc_getFunctionClose(c_file)(c_file, fid1); smbc_getFunctionClose(c_print)(c_print, fid2); errno = saverr; - } - } - + saverr = errno; - + smbc_getFunctionClose(c_file)(c_file, fid1); smbc_getFunctionClose(c_print)(c_print, fid2); - + if (bytes < 0) { - errno = saverr; TALLOC_FREE(frame); return -1; - } - + TALLOC_FREE(frame); return tot_bytes; - } /* @@ -190,22 +176,21 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, char *workgroup = NULL; char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - + if (SMBC_parse_path(frame, context, fname, @@ -220,7 +205,7 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -229,25 +214,24 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (cli_print_queue(srv->cli, (void (*)(struct print_job_info *))fn) < 0) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } - + TALLOC_FREE(frame); return 0; - } /* @@ -268,22 +252,21 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, char *path = NULL; int err; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - + if (SMBC_parse_path(frame, context, fname, @@ -298,7 +281,7 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -307,30 +290,25 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { - TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ - } - + if ((err = cli_printjob_del(srv->cli, id)) != 0) { - if (err < 0) errno = SMBC_errno(context, srv->cli); else if (err == ERRnosuchprintjob) errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + TALLOC_FREE(frame); return 0; - } diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c index 3493e4f8dd..fc3f321497 100644 --- a/source3/libsmb/libsmb_setget.c +++ b/source3/libsmb/libsmb_setget.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 95c5c52d6e..f8614d3154 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -36,15 +36,12 @@ generate_inode(SMBCCTX *context, const char *name) { if (!context || !context->internal->initialized) { - errno = EINVAL; return -1; - } - + if (!*name) return 2; /* FIXME, why 2 ??? */ return (ino_t)str_checksum(name); - } /* @@ -60,20 +57,20 @@ setup_stat(SMBCCTX *context, int mode) { TALLOC_CTX *frame = talloc_stackframe(); - + st->st_mode = 0; - + if (IS_DOS_DIR(mode)) { st->st_mode = SMBC_DIR_MODE; } else { st->st_mode = SMBC_FILE_MODE; } - + if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; - + st->st_size = size; #ifdef HAVE_STAT_ST_BLKSIZE st->st_blksize = 512; @@ -86,20 +83,19 @@ setup_stat(SMBCCTX *context, #endif st->st_uid = getuid(); st->st_gid = getgid(); - + if (IS_DOS_DIR(mode)) { st->st_nlink = 2; } else { st->st_nlink = 1; } - + if (st->st_ino == 0) { st->st_ino = generate_inode(context, fname); } - + TALLOC_FREE(frame); return True; /* FIXME: Is this needed ? */ - } /* @@ -125,22 +121,21 @@ SMBC_stat_ctx(SMBCCTX *context, uint16 mode = 0; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_stat(%s)\n", fname)); - + if (SMBC_parse_path(frame, context, fname, @@ -164,15 +159,14 @@ SMBC_stat_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (!SMBC_getatr(context, srv, path, &mode, &size, NULL, &access_time_ts, @@ -183,19 +177,18 @@ SMBC_stat_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + st->st_ino = ino; - + setup_stat(context, st, (char *) fname, size, mode); - + st->st_atime = convert_timespec_to_time_t(access_time_ts); st->st_ctime = convert_timespec_to_time_t(change_time_ts); st->st_mtime = convert_timespec_to_time_t(write_time_ts); st->st_dev = srv->dev; - + TALLOC_FREE(frame); return 0; - } /* @@ -221,25 +214,24 @@ SMBC_fstat_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + if (!file->file) { TALLOC_FREE(frame); return smbc_getFunctionFstatdir(context)(context, file, st); } - + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, @@ -255,7 +247,7 @@ SMBC_fstat_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", context->internal->auth_info, file->srv->cli, path, @@ -266,41 +258,37 @@ SMBC_fstat_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, NULL, &access_time_ts, &write_time_ts, &change_time_ts, &ino)) { - time_t change_time, access_time, write_time; - + if (!NT_STATUS_IS_OK(cli_getattrE(targetcli, file->cli_fd, &mode, &size, &change_time, &access_time, &write_time))) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - change_time_ts = convert_time_t_to_timespec(change_time); access_time_ts = convert_time_t_to_timespec(access_time); write_time_ts = convert_time_t_to_timespec(write_time); } - + st->st_ino = ino; - + setup_stat(context, st, file->fname, size, mode); - + st->st_atime = convert_timespec_to_time_t(access_time_ts); st->st_ctime = convert_timespec_to_time_t(change_time_ts); st->st_mtime = convert_timespec_to_time_t(write_time_ts); st->st_dev = file->srv->dev; - + TALLOC_FREE(frame); return 0; - } @@ -368,7 +356,6 @@ SMBC_fstatvfs_ctx(SMBCCTX *context, unsigned long flags = 0; uint32 fs_attrs = 0; struct cli_state *cli = file->srv->cli; - /* Initialize all fields (at least until we actually use them) */ memset(st, 0, sizeof(*st)); @@ -389,7 +376,7 @@ SMBC_fstatvfs_ctx(SMBCCTX *context, uint64_t actual_allocation_units; uint64_t sectors_per_allocation_unit; uint64_t bytes_per_sector; - + /* Nope. If size data is available... */ if (cli_get_fs_full_size_info(cli, &total_allocation_units, diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 0e2ffda7a2..27c3e12399 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -34,17 +34,15 @@ static struct rpc_pipe_client * find_lsa_pipe_hnd(struct cli_state *ipc_cli) { struct rpc_pipe_client *pipe_hnd; - + for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) { - if (ndr_syntax_id_equal(&pipe_hnd->abstract_syntax, &ndr_table_lsarpc.syntax_id)) { return pipe_hnd; } } - return NULL; } @@ -60,19 +58,19 @@ ace_compare(SEC_ACE *ace1, { bool b1; bool b2; - + /* If the ACEs are equal, we have nothing more to do. */ if (sec_ace_equal(ace1, ace2)) { return 0; } - + /* Inherited follow non-inherited */ b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); if (b1 != b2) { return (b1 ? 1 : -1); } - + /* * What shall we do with AUDITs and ALARMs? It's undefined. We'll * sort them after DENY and ALLOW. @@ -88,7 +86,7 @@ ace_compare(SEC_ACE *ace1, if (b1 != b2) { return (b1 ? 1 : -1); } - + /* Allowed ACEs follow denied ACEs */ b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); @@ -97,7 +95,7 @@ ace_compare(SEC_ACE *ace1, if (b1 != b2) { return (b1 ? 1 : -1); } - + /* * ACEs applying to an entity's object follow those applying to the * entity itself @@ -109,34 +107,34 @@ ace_compare(SEC_ACE *ace1, if (b1 != b2) { return (b1 ? 1 : -1); } - + /* * If we get this far, the ACEs are similar as far as the * characteristics we typically care about (those defined by the * referenced MS document). We'll now sort by characteristics that * just seems reasonable. */ - + if (ace1->type != ace2->type) { return ace2->type - ace1->type; } - + if (sid_compare(&ace1->trustee, &ace2->trustee)) { return sid_compare(&ace1->trustee, &ace2->trustee); } - + if (ace1->flags != ace2->flags) { return ace1->flags - ace2->flags; } - + if (ace1->access_mask != ace2->access_mask) { return ace1->access_mask - ace2->access_mask; } - + if (ace1->size != ace2->size) { return ace1->size - ace2->size; } - + return memcmp(ace1, ace2, sizeof(SEC_ACE)); } @@ -146,10 +144,10 @@ sort_acl(SEC_ACL *the_acl) { uint32 i; if (!the_acl) return; - + qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare); - + for (i=1;i<the_acl->num_aces;) { if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { int j; @@ -176,21 +174,21 @@ convert_sid_to_string(struct cli_state *ipc_cli, enum lsa_SidType *types = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); TALLOC_CTX *ctx; - + sid_to_fstring(str, sid); - + if (numeric) { return; /* no lookup desired */ } - + if (!pipe_hnd) { return; } - + /* Ask LSA to convert the sid to a name */ - + ctx = talloc_stackframe(); - + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, pol, 1, sid, &domains, &names, &types)) || @@ -198,9 +196,9 @@ convert_sid_to_string(struct cli_state *ipc_cli, TALLOC_FREE(ctx); return; } - + /* Converted OK */ - + slprintf(str, sizeof(fstring) - 1, "%s%s%s", domains[0], lp_winbind_separator(), names[0]); @@ -221,20 +219,20 @@ convert_string_to_sid(struct cli_state *ipc_cli, bool result = True; TALLOC_CTX *ctx = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); - + if (!pipe_hnd) { return False; } - + if (numeric) { if (strncmp(str, "S-", 2) == 0) { return string_to_sid(sid, str); } - + result = False; goto done; } - + ctx = talloc_stackframe(); if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, pol, 1, &str, @@ -243,10 +241,9 @@ convert_string_to_sid(struct cli_state *ipc_cli, result = False; goto done; } - + sid_copy(sid, &sids[0]); done: - TALLOC_FREE(ctx); return result; } @@ -274,7 +271,7 @@ parse_ace(struct cli_state *ipc_cli, uint32 mask; }; TALLOC_CTX *frame = talloc_stackframe(); - + /* These values discovered by inspection */ static const struct perm_value special_values[] = { { "R", 0x00120089 }, @@ -285,15 +282,14 @@ parse_ace(struct cli_state *ipc_cli, { "O", 0x00080000 }, { "", 0 }, }; - + static const struct perm_value standard_values[] = { { "READ", 0x001200a9 }, { "CHANGE", 0x001301bf }, { "FULL", 0x001f01ff }, { "", 0 }, }; - - + ZERO_STRUCTP(ace); p = strchr_m(str,':'); if (!p) { @@ -303,25 +299,25 @@ parse_ace(struct cli_state *ipc_cli, *p = '\0'; p++; /* Try to parse numeric form */ - + if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { goto done; } - + /* Try to parse text form */ - + if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { TALLOC_FREE(frame); return false; } - + cp = p; if (!next_token_talloc(frame, &cp, &tok, "/")) { TALLOC_FREE(frame); return false; } - + if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { atype = SEC_ACE_TYPE_ACCESS_ALLOWED; } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { @@ -330,20 +326,20 @@ parse_ace(struct cli_state *ipc_cli, TALLOC_FREE(frame); return false; } - + /* Only numeric form accepted for flags at present */ - + if (!(next_token_talloc(frame, &cp, &tok, "/") && sscanf(tok, "%i", &aflags))) { TALLOC_FREE(frame); return false; } - + if (!next_token_talloc(frame, &cp, &tok, "/")) { TALLOC_FREE(frame); return false; } - + if (strncmp(tok, "0x", 2) == 0) { if (sscanf(tok, "%i", &amask) != 1) { TALLOC_FREE(frame); @@ -351,38 +347,38 @@ parse_ace(struct cli_state *ipc_cli, } goto done; } - + for (v = standard_values; v->perm; v++) { if (strcmp(tok, v->perm) == 0) { amask = v->mask; goto done; } } - + p = tok; - + while(*p) { bool found = False; - + for (v = special_values; v->perm; v++) { if (v->perm[0] == *p) { amask |= v->mask; found = True; } } - + if (!found) { TALLOC_FREE(frame); return false; } p++; } - + if (*p) { TALLOC_FREE(frame); return false; } - + done: mask = amask; init_sec_ace(ace, &sid, atype, mask, aflags); @@ -398,12 +394,12 @@ add_ace(SEC_ACL **the_acl, { SEC_ACL *newacl; SEC_ACE *aces; - + if (! *the_acl) { (*the_acl) = make_sec_acl(ctx, 3, 1, ace); return True; } - + if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { return False; @@ -434,14 +430,14 @@ sec_desc_parse(TALLOC_CTX *ctx, DOM_SID *owner_sid=NULL; SEC_ACL *dacl=NULL; int revision=1; - + while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { - + if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { revision = strtol(tok+9, NULL, 16); continue; } - + if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { if (owner_sid) { DEBUG(5,("OWNER specified more than once!\n")); @@ -457,7 +453,7 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { if (owner_sid) { DEBUG(5,("OWNER specified more than once!\n")); @@ -473,7 +469,7 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { if (group_sid) { DEBUG(5,("GROUP specified more than once!\n")); @@ -489,7 +485,7 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { if (group_sid) { DEBUG(5,("GROUP specified more than once!\n")); @@ -505,7 +501,7 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"ACL:", 4) == 0) { SEC_ACE ace; if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { @@ -518,7 +514,7 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { SEC_ACE ace; if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { @@ -531,18 +527,17 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + DEBUG(5, ("Failed to parse security descriptor\n")); goto done; } - + ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, owner_sid, group_sid, NULL, dacl, &sd_size); - + done: SAFE_FREE(group_sid); SAFE_FREE(owner_sid); - return ret; } @@ -562,13 +557,13 @@ dos_attr_query(SMBCCTX *context, uint16 mode = 0; SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; - + ret = TALLOC_P(ctx, DOS_ATTR_DESC); if (!ret) { errno = ENOMEM; return NULL; } - + /* Obtain the DOS attributes */ if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename), &mode, &size, @@ -581,7 +576,7 @@ dos_attr_query(SMBCCTX *context, DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); return NULL; } - + ret->mode = mode; ret->size = size; ret->create_time = convert_timespec_to_time_t(create_time_ts); @@ -589,7 +584,7 @@ dos_attr_query(SMBCCTX *context, ret->write_time = convert_timespec_to_time_t(write_time_ts); ret->change_time = convert_timespec_to_time_t(change_time_ts); ret->inode = inode; - + return ret; } @@ -611,7 +606,7 @@ dos_attr_parse(SMBCCTX *context, const char * write_time_attr; const char * change_time_attr; } attr_strings; - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -626,7 +621,7 @@ dos_attr_parse(SMBCCTX *context, attr_strings.write_time_attr = "M_TIME"; attr_strings.change_time_attr = "C_TIME"; } - + /* if this is to set the entire ACL... */ if (*str == '*') { /* ... then increment past the first colon if there is one */ @@ -636,7 +631,7 @@ dos_attr_parse(SMBCCTX *context, p = str; } } - + frame = talloc_stackframe(); while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { if (StrnCaseCmp(tok, "MODE:", 5) == 0) { @@ -651,30 +646,30 @@ dos_attr_parse(SMBCCTX *context, } continue; } - + if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { dad->size = (SMB_OFF_T)atof(tok+5); continue; } - + n = strlen(attr_strings.access_time_attr); if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - + n = strlen(attr_strings.change_time_attr); if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - + n = strlen(attr_strings.write_time_attr); if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - + if (attr_strings.create_time_attr != NULL) { n = strlen(attr_strings.create_time_attr); if (StrnCaseCmp(tok, attr_strings.create_time_attr, @@ -684,7 +679,7 @@ dos_attr_parse(SMBCCTX *context, continue; } } - + if (StrnCaseCmp(tok, "INODE:", 6) == 0) { dad->inode = (SMB_INO_T)atof(tok+6); continue; @@ -761,7 +756,7 @@ cacl_get(SMBCCTX *context, const char * write_time_attr; const char * change_time_attr; } excl_attr_strings; - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -769,7 +764,7 @@ cacl_get(SMBCCTX *context, attr_strings.access_time_attr = "ACCESS_TIME"; attr_strings.write_time_attr = "WRITE_TIME"; attr_strings.change_time_attr = "CHANGE_TIME"; - + excl_attr_strings.create_time_attr = "CREATE_TIME"; excl_attr_strings.access_time_attr = "ACCESS_TIME"; excl_attr_strings.write_time_attr = "WRITE_TIME"; @@ -780,28 +775,28 @@ cacl_get(SMBCCTX *context, attr_strings.access_time_attr = "A_TIME"; attr_strings.write_time_attr = "M_TIME"; attr_strings.change_time_attr = "C_TIME"; - + excl_attr_strings.create_time_attr = NULL; excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; } - + /* Copy name so we can strip off exclusions (if any are specified) */ strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); - + /* Ensure name is null terminated */ name_sandbox[sizeof(name_sandbox) - 1] = '\0'; - + /* Play in the sandbox */ name = name_sandbox; - + /* If there are any exclusions, point to them and mask them from name */ if ((pExclude = strchr(name, '!')) != NULL) { *pExclude++ = '\0'; } - + all = (StrnCaseCmp(name, "system.*", 8) == 0); all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); @@ -809,21 +804,20 @@ cacl_get(SMBCCTX *context, some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); numeric = (* (name + strlen(name) - 1) != '+'); - + /* Look for exclusions from "all" requests */ if (all || all_nt || all_dos) { - /* Exclusions are delimited by '!' */ for (; pExclude != NULL; pExclude = (p == NULL ? NULL : p + 1)) { - + /* Find end of this exclusion name */ if ((p = strchr(pExclude, '!')) != NULL) { *p = '\0'; } - + /* Which exclusion name is this? */ if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) { @@ -877,9 +871,9 @@ cacl_get(SMBCCTX *context, } } } - + n_used = 0; - + /* * If we are (possibly) talking to an NT or new system and some NT * attributes have been requested... @@ -950,7 +944,7 @@ cacl_get(SMBCCTX *context, sd->revision); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -960,7 +954,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_nt_owner) { /* Get owner and group sid */ if (sd->owner_sid) { @@ -971,7 +965,7 @@ cacl_get(SMBCCTX *context, } else { fstrcpy(sidstr, ""); } - + if (all || all_nt) { if (determine_size) { p = talloc_asprintf(ctx, ",OWNER:%s", @@ -998,7 +992,7 @@ cacl_get(SMBCCTX *context, sidstr); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1008,7 +1002,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_nt_group) { if (sd->group_sid) { convert_sid_to_string(ipc_cli, pol, @@ -1017,7 +1011,7 @@ cacl_get(SMBCCTX *context, } else { fstrcpy(sidstr, ""); } - + if (all || all_nt) { if (determine_size) { p = talloc_asprintf(ctx, ",GROUP:%s", @@ -1044,7 +1038,7 @@ cacl_get(SMBCCTX *context, "%s", sidstr); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1054,16 +1048,16 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_nt_acl) { /* Add aces to value buffer */ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - + SEC_ACE *ace = &sd->dacl->aces[i]; convert_sid_to_string(ipc_cli, pol, sidstr, numeric, &ace->trustee); - + if (all || all_nt) { if (determine_size) { p = talloc_asprintf( @@ -1146,15 +1140,15 @@ cacl_get(SMBCCTX *context, n = 0; } } - + /* Restore name pointer to its original value */ name -= 19; } - + if (all || some_dos) { /* Point to the portion after "system.dos_attr." */ name += 16; /* if (all) this will be invalid but unused */ - + /* Obtain the DOS attributes */ if (!SMBC_getatr(context, srv, filename, &mode, &size, &create_time_ts, @@ -1162,17 +1156,16 @@ cacl_get(SMBCCTX *context, &write_time_ts, &change_time_ts, &ino)) { - + errno = SMBC_errno(context, srv->cli); return -1; - } - + create_time = convert_timespec_to_time_t(create_time_ts); access_time = convert_timespec_to_time_t(access_time_ts); write_time = convert_timespec_to_time_t(write_time_ts); change_time = convert_timespec_to_time_t(change_time_ts); - + if (! exclude_dos_mode) { if (all || all_dos) { if (determine_size) { @@ -1210,7 +1203,7 @@ cacl_get(SMBCCTX *context, "0x%x", mode); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1220,7 +1213,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_size) { if (all || all_dos) { if (determine_size) { @@ -1255,7 +1248,7 @@ cacl_get(SMBCCTX *context, (double)size); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1265,7 +1258,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_create_time && attr_strings.create_time_attr != NULL) { if (all || all_dos) { @@ -1298,7 +1291,7 @@ cacl_get(SMBCCTX *context, "%lu", (unsigned long) create_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1308,7 +1301,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_access_time) { if (all || all_dos) { if (determine_size) { @@ -1340,7 +1333,7 @@ cacl_get(SMBCCTX *context, "%lu", (unsigned long) access_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1350,7 +1343,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_write_time) { if (all || all_dos) { if (determine_size) { @@ -1382,7 +1375,7 @@ cacl_get(SMBCCTX *context, "%lu", (unsigned long) write_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1392,7 +1385,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_change_time) { if (all || all_dos) { if (determine_size) { @@ -1424,7 +1417,7 @@ cacl_get(SMBCCTX *context, "%lu", (unsigned long) change_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1434,7 +1427,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_inode) { if (all || all_dos) { if (determine_size) { @@ -1469,7 +1462,7 @@ cacl_get(SMBCCTX *context, (double) ino); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1479,16 +1472,16 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + /* Restore name pointer to its original value */ name -= 16; } - + if (n_used == 0) { errno = ENOATTR; return -1; } - + return n_used; } @@ -1525,24 +1518,23 @@ cacl_set(SMBCCTX *context, numeric = ((p = strchr(the_acl, ':')) != NULL && p > the_acl && p[-1] != '+'); - + /* if this is to set the entire ACL... */ if (*the_acl == '*') { /* ... then increment past the first colon */ the_acl = p + 1; } - + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl); - if (!sd) { errno = EINVAL; return -1; } } - + /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller that doesn't deref sd */ - + if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { errno = EINVAL; return -1; @@ -1601,7 +1593,7 @@ cacl_set(SMBCCTX *context, break; } } - + if (!found) { err = ENOATTR; ret = -1; @@ -1609,11 +1601,11 @@ cacl_set(SMBCCTX *context, } } break; - + case SMBC_XATTR_MODE_ADD: for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { bool found = False; - + for (j=0;old->dacl && j<old->dacl->num_aces;j++) { if (sid_equal(&sd->dacl->aces[i].trustee, &old->dacl->aces[j].trustee)) { @@ -1627,43 +1619,43 @@ cacl_set(SMBCCTX *context, found = True; } } - + if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { err = ENOATTR; ret = -1; goto failed; } - + for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { add_ace(&old->dacl, &sd->dacl->aces[i], ctx); } } dacl = old->dacl; break; - + case SMBC_XATTR_MODE_SET: old = sd; owner_sid = old->owner_sid; group_sid = old->group_sid; dacl = old->dacl; break; - + case SMBC_XATTR_MODE_CHOWN: owner_sid = sd->owner_sid; break; - + case SMBC_XATTR_MODE_CHGRP: group_sid = sd->group_sid; break; } - + /* Denied ACE entries must come before allowed ones */ sort_acl(old->dacl); - + /* Create new security descriptor and set it */ sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, owner_sid, group_sid, NULL, dacl, &sd_size); - + if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetpath, 0, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) { @@ -1672,22 +1664,22 @@ cacl_set(SMBCCTX *context, errno = 0; return -1; } - + if (!cli_set_secdesc(targetcli, fnum, sd)) { DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(targetcli))); ret = -1; } - + /* Clean up */ - + failed: cli_close(targetcli, fnum); - + if (err != 0) { errno = err; } - + return ret; } @@ -1718,23 +1710,22 @@ SMBC_setxattr_ctx(SMBCCTX *context, const char * change_time_attr; } attr_strings; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (const char*)value)); - + if (SMBC_parse_path(frame, context, fname, @@ -1749,7 +1740,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -1758,14 +1749,14 @@ SMBC_setxattr_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (! srv->no_nt_session) { ipc_srv = SMBC_attr_server(frame, context, server, share, &workgroup, &user, &password); @@ -1775,7 +1766,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + /* * Are they asking to set the entire set of known attributes? */ @@ -1791,7 +1782,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (ipc_srv) { ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, @@ -1803,13 +1794,13 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { ret = 0; } - + /* get a DOS Attribute Descriptor with current attributes */ dad = dos_attr_query(context, talloc_tos(), path, srv); if (dad) { /* Overwrite old with new, using what was provided */ dos_attr_parse(context, dad, srv, namevalue); - + /* Set the new DOS attributes */ if (! SMBC_setatr(context, srv, path, dad->create_time, @@ -1817,12 +1808,12 @@ SMBC_setxattr_ctx(SMBCCTX *context, dad->write_time, dad->change_time, dad->mode)) { - + /* cause failure if NT failed too */ dad = NULL; } } - + /* we only fail if both NT and DOS sets failed */ if (ret < 0 && ! dad) { ret = -1; /* in case dad was null */ @@ -1830,11 +1821,11 @@ SMBC_setxattr_ctx(SMBCCTX *context, else { ret = 0; } - + TALLOC_FREE(frame); return ret; } - + /* * Are they asking to set an access control element or to set * the entire access control list? @@ -1844,12 +1835,12 @@ SMBC_setxattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - + /* Yup. */ char *namevalue = talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); - + if (! ipc_srv) { ret = -1; /* errno set by SMBC_server() */ } @@ -1868,18 +1859,18 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* * Are they asking to set the owner? */ if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { - + /* Yup. */ char *namevalue = talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); - + if (! ipc_srv) { ret = -1; /* errno set by SMBC_server() */ } @@ -1894,18 +1885,18 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* * Are they asking to set the group? */ if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { - + /* Yup. */ char *namevalue = talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); - + if (! ipc_srv) { /* errno set by SMBC_server() */ ret = -1; @@ -1921,7 +1912,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -1936,7 +1927,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, attr_strings.write_time_attr = "system.dos_attr.M_TIME"; attr_strings.change_time_attr = "system.dos_attr.C_TIME"; } - + /* * Are they asking to set a DOS attribute? */ @@ -1947,7 +1938,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, StrCaseCmp(name, attr_strings.access_time_attr) == 0 || StrCaseCmp(name, attr_strings.write_time_attr) == 0 || StrCaseCmp(name, attr_strings.change_time_attr) == 0) { - + /* get a DOS Attribute Descriptor with current attributes */ dad = dos_attr_query(context, talloc_tos(), path, srv); if (dad) { @@ -1960,7 +1951,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { /* Overwrite old with provided new params */ dos_attr_parse(context, dad, srv, namevalue); - + /* Set the new DOS attributes */ ret2 = SMBC_setatr(context, srv, path, dad->create_time, @@ -1968,7 +1959,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, dad->write_time, dad->change_time, dad->mode); - + /* ret2 has True (success) / False (failure) */ if (ret2) { ret = 0; @@ -1979,11 +1970,11 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { ret = -1; } - + TALLOC_FREE(frame); return ret; } - + /* Unsupported attribute name */ errno = EINVAL; TALLOC_FREE(frame); @@ -2013,22 +2004,21 @@ SMBC_getxattr_ctx(SMBCCTX *context, const char * change_time_attr; } attr_strings; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); - + if (SMBC_parse_path(frame, context, fname, @@ -2043,7 +2033,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -2052,14 +2042,14 @@ SMBC_getxattr_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (! srv->no_nt_session) { ipc_srv = SMBC_attr_server(frame, context, server, share, &workgroup, &user, &password); @@ -2069,7 +2059,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -2084,7 +2074,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, attr_strings.write_time_attr = "system.dos_attr.M_TIME"; attr_strings.change_time_attr = "system.dos_attr.C_TIME"; } - + /* Are they requesting a supported attribute? */ if (StrCaseCmp(name, "system.*") == 0 || StrnCaseCmp(name, "system.*!", 9) == 0 || @@ -2111,7 +2101,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, StrCaseCmp(name, attr_strings.write_time_attr) == 0 || StrCaseCmp(name, attr_strings.change_time_attr) == 0 || StrCaseCmp(name, "system.dos_attr.inode") == 0) { - + /* Yup. */ char *filename = (char *) name; ret = cacl_get(context, talloc_tos(), srv, @@ -2126,7 +2116,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* Unsupported attribute name */ errno = EINVAL; TALLOC_FREE(frame); @@ -2149,22 +2139,21 @@ SMBC_removexattr_ctx(SMBCCTX *context, char *workgroup = NULL; char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); - + if (SMBC_parse_path(frame, context, fname, @@ -2179,7 +2168,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -2188,14 +2177,14 @@ SMBC_removexattr_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (! srv->no_nt_session) { ipc_srv = SMBC_attr_server(frame, context, server, share, &workgroup, &user, &password); @@ -2205,16 +2194,16 @@ SMBC_removexattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + if (! ipc_srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_attr_server */ } - + /* Are they asking to set the entire ACL? */ if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { - + /* Yup. */ ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, @@ -2222,7 +2211,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* * Are they asking to remove one or more spceific security descriptor * attributes? @@ -2234,7 +2223,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - + /* Yup. */ ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, @@ -2243,7 +2232,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* Unsupported attribute name */ errno = EINVAL; TALLOC_FREE(frame); @@ -2302,7 +2291,7 @@ SMBC_listxattr_ctx(SMBCCTX *context, "system.dos_attr.change_time\0" ; const char * supported; - + if (context->internal->full_time_names) { supported = supported_new; retsize = sizeof(supported_new); @@ -2310,16 +2299,16 @@ SMBC_listxattr_ctx(SMBCCTX *context, supported = supported_old; retsize = sizeof(supported_old); } - + if (size == 0) { return retsize; } - + if (retsize > size) { errno = ERANGE; return -1; } - + /* this can't be strcpy() because there are embedded null characters */ memcpy(list, supported, retsize); return retsize; |