-/*
+/*
Unix SMB/Netbios implementation.
SMB client library implementation
Copyright (C) Andrew Tridgell 1998
Copyright (C) Richard Sharpe 2000, 2002
Copyright (C) John Terpstra 2000
- Copyright (C) Tom Jansen (Ninja ISD) 2002
+ 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/>.
*/
int comment_len = (comment == NULL ? 0 : strlen(comment));
/*
- * Allocate space for the dirent, which must be increased by the
+ * Allocate space for the dirent, which must be increased by the
* size of the name and the comment and 1 each for the null terminator.
*/
size = sizeof(struct smbc_dirent) + name_length + comment_len + 2;
-
+
dirent = (struct smbc_dirent *)SMB_MALLOC(size);
if (!dirent) {
else {
dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list);
-
+
if (!dir->dir_end->next) {
-
+
SAFE_FREE(dirent);
dir->dir_error = ENOMEM;
return -1;
dir->dir_end->next = NULL;
dir->dir_end->dirent = dirent;
-
+
dirent->smbc_type = type;
dirent->namelen = name_length;
dirent->commentlen = comment_len;
dirent->dirlen = size;
-
+
/*
* dirent->namelen + 1 includes the null (no null termination needed)
* Ditto for dirent->commentlen.
strncpy(dirent->name, (name?name:""), dirent->namelen + 1);
dirent->comment = (char *)(&dirent->name + dirent->namelen + 1);
strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1);
-
+
return 0;
}
void *state)
{
- if (add_dirent((SMBCFILE *)state, finfo->name, "",
+ if (add_dirent((SMBCFILE *)state, finfo->name, "",
(finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) {
/* Handle an error ... */
/* FIXME: Add some code ... */
- }
+ }
}
{
int i;
WERROR result;
- ENUM_HND enum_hnd;
- uint32 info_level = 1;
uint32 preferred_len = 0xffffffff;
uint32 type;
- SRV_SHARE_INFO_CTR ctr;
+ struct srvsvc_NetShareInfoCtr info_ctr;
+ struct srvsvc_NetShareCtr1 ctr1;
fstring name = "";
fstring comment = "";
struct rpc_pipe_client *pipe_hnd;
NTSTATUS nt_status;
+ uint32_t resume_handle = 0;
+ uint32_t total_entries = 0;
/* Open the server service pipe */
- pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status);
- if (!pipe_hnd) {
+ nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id,
+ &pipe_hnd);
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("net_share_enum_rpc pipe open fail!\n"));
return -1;
}
+ ZERO_STRUCT(info_ctr);
+ ZERO_STRUCT(ctr1);
+
+ info_ctr.level = 1;
+ info_ctr.ctr.ctr1 = &ctr1;
+
/* Issue the NetShareEnum RPC call and retrieve the response */
- init_enum_hnd(&enum_hnd, 0);
- result = rpccli_srvsvc_net_share_enum(pipe_hnd,
- talloc_tos(),
- info_level,
- &ctr,
- preferred_len,
- &enum_hnd);
+ nt_status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, talloc_tos(),
+ pipe_hnd->desthost,
+ &info_ctr,
+ preferred_len,
+ &total_entries,
+ &resume_handle,
+ &result);
/* Was it successful? */
- if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) {
+ if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result) ||
+ total_entries == 0) {
/* Nope. Go clean up. */
goto done;
}
/* For each returned entry... */
- for (i = 0; i < ctr.num_entries; i++) {
+ for (i = 0; i < total_entries; i++) {
/* pull out the share name */
- rpcstr_pull_unistr2_fstring(
- name, &ctr.share.info1[i].info_1_str.uni_netname);
+ fstrcpy(name, info_ctr.ctr.ctr1->array[i].name);
/* pull out the share's comment */
- rpcstr_pull_unistr2_fstring(
- comment, &ctr.share.info1[i].info_1_str.uni_remark);
+ fstrcpy(comment, info_ctr.ctr.ctr1->array[i].comment);
/* Get the type value */
- type = ctr.share.info1[i].info_1.type;
+ type = info_ctr.ctr.ctr1->array[i].type;
/* Add this share to the list */
(*fn)(name, type, comment, state);
done:
/* Close the server service pipe */
- cli_rpc_pipe_close(pipe_hnd);
+ TALLOC_FREE(pipe_hnd);
/* Tell 'em if it worked */
return W_ERROR_IS_OK(result) ? 0 : -1;
const char *fname)
{
int saved_errno;
- char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *options = NULL;
char *workgroup = NULL;
char *path = NULL;
uint16 mode;
struct sockaddr_storage rem_ss;
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
DEBUG(4, ("no valid context\n"));
errno = EINVAL + 8192;
TALLOC_FREE(frame);
}
if (SMBC_parse_path(frame,
- context,
- fname,
- &workgroup,
- &server,
- &share,
- &path,
- &user,
- &password,
- &options)) {
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ &options)) {
DEBUG(4, ("no valid path\n"));
errno = EINVAL + 8194;
TALLOC_FREE(frame);
}
if (!user || user[0] == (char)0) {
- user = talloc_strdup(frame, context->user);
+ user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
errno = ENOMEM;
TALLOC_FREE(frame);
}
/* Determine how many local master browsers to query */
- max_lmb_count = (context->browse_max_lmb_count == 0
+ max_lmb_count = (smbc_getOptionBrowseMaxLmbCount(context) == 0
? INT_MAX
- : context->browse_max_lmb_count);
+ : smbc_getOptionBrowseMaxLmbCount(context));
memset(&u_info, '\0', sizeof(u_info));
u_info.username = talloc_strdup(frame,user);
ip_list = NULL;
if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
- &count)))
+ &count)))
{
SAFE_FREE(ip_list);
* establish a connection if one does not already
* exist.
*/
- srv = SMBC_server(frame, context, False, server, "IPC$",
+ srv = SMBC_server(frame, context, False,
+ server, "IPC$",
&workgroup, &user, &password);
/*
if (!name_status_find(server, 0, 0,
&rem_ss, buserver)) {
- DEBUG(0, ("Could not get name of "
- "local/domain master browser "
- "for server %s\n", server));
+ DEBUG(0,("Could not get name of "
+ "local/domain master browser "
+ "for server %s\n", server));
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
*/
srv = SMBC_server(frame, context, True,
buserver, "IPC$",
- &workgroup, &user, &password);
+ &workgroup,
+ &user, &password);
if (!srv) {
DEBUG(0, ("got no contact to IPC$\n"));
if (dir) {
} else if (srv ||
(resolve_name(server, &rem_ss, 0x20))) {
- /* If we hadn't found the server, get one now */
+ /*
+ * If we hadn't found the server, get one now
+ */
if (!srv) {
srv = SMBC_server(frame, context, True,
server, "IPC$",
saved_errno = SMBC_errno(context, targetcli);
if (saved_errno == EINVAL) {
- /*
- * See if they asked to opendir something
- * other than a directory. If so, the
- * converted error value we got would have
- * been EINVAL rather than ENOTDIR.
- */
- *p = '\0'; /* restore original path */
-
- if (SMBC_getatr(context, srv, path,
- &mode, NULL,
- NULL, NULL, NULL, NULL,
- NULL) &&
- ! IS_DOS_DIR(mode)) {
-
- /* It is. Correct the error value */
- saved_errno = ENOTDIR;
- }
+ /*
+ * See if they asked to opendir
+ * something other than a directory.
+ * If so, the converted error value we
+ * got would have been EINVAL rather
+ * than ENOTDIR.
+ */
+ *p = '\0'; /* restore original path */
+
+ if (SMBC_getatr(context, srv, path,
+ &mode, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL) &&
+ ! IS_DOS_DIR(mode)) {
+
+ /* It is. Correct the error value */
+ saved_errno = ENOTDIR;
+ }
}
/*
* good any more...
*/
if (cli_is_error(targetcli) &&
- (context->server.check_server_fn)(context, srv)) {
+ smbc_getFunctionCheckServer(context)(context, srv)) {
/* ... then remove it. */
- if ((context->server.remove_unused_server_fn)(context,
- srv)) {
+ if (smbc_getFunctionRemoveUnusedServer(context)(context,
+ srv)) {
/*
* We could not remove the
* server completely, remove
* will be removed when the
* last file/dir is closed.
*/
- (context->cache.remove_cached_server_fn)(context, srv);
+ smbc_getFunctionRemoveCachedServer(context)(context, srv);
}
}
}
- DLIST_ADD(context->files, dir);
+ DLIST_ADD(context->internal->files, dir);
TALLOC_FREE(frame);
return dir;
{
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
- if (!dir || !SMBC_dlist_contains(context->files, dir)) {
+ if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
errno = EBADF;
TALLOC_FREE(frame);
return -1;
remove_dir(dir); /* Clean it up */
- DLIST_REMOVE(context->files, dir);
+ DLIST_REMOVE(context->internal->files, dir);
if (dir) {
struct smbc_dirent *src,
int max_namebuf_len)
{
- if (context->urlencode_readdir_entries) {
+ if (smbc_getOptionUrlEncodeReaddirEntries(context)) {
/* url-encode the name. get back remaining buffer space */
max_namebuf_len =
memcpy(dest, src, src->dirlen);
dest->comment = (char *)(&dest->name + src->namelen + 1);
}
-
+
}
/*
/* Check that all is ok first ... */
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
DEBUG(0, ("Invalid context in SMBC_readdir_ctx()\n"));
}
- if (!dir || !SMBC_dlist_contains(context->files, dir)) {
+ if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
errno = EBADF;
DEBUG(0, ("Invalid dir in SMBC_readdir_ctx()\n"));
}
- dirp = (struct smbc_dirent *)context->dirent;
- maxlen = (sizeof(context->dirent) -
+ dirp = (struct smbc_dirent *)context->internal->dirent;
+ maxlen = (sizeof(context->internal->dirent) -
sizeof(struct smbc_dirent));
smbc_readdir_internal(context, dirp, dirent, maxlen);
/* Check that all is ok first ... */
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
TALLOC_FREE(frame);
}
- if (!dir || !SMBC_dlist_contains(context->files, dir)) {
+ if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
errno = EBADF;
TALLOC_FREE(frame);
return -1;
-
+
}
if (dir->file != False) { /* FIXME, should be dir, perhaps */
}
- /*
+ /*
* Now, retrieve the number of entries that will fit in what was passed
- * We have to figure out if the info is in the list, or we need to
+ * We have to figure out if the info is in the list, or we need to
* send a request to the server to get the info.
*/
}
/* Do urlencoding of next entry, if so selected */
- dirent = (struct smbc_dirent *)context->dirent;
- maxlen = (sizeof(context->dirent) -
+ dirent = (struct smbc_dirent *)context->internal->dirent;
+ maxlen = (sizeof(context->internal->dirent) -
sizeof(struct smbc_dirent));
- smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen);
+ smbc_readdir_internal(context, dirent,
+ dirlist->dirent, maxlen);
reqd = dirent->dirlen;
}
memcpy(ndir, dirent, reqd); /* Copy the data in ... */
-
- ((struct smbc_dirent *)ndir)->comment =
+
+ ((struct smbc_dirent *)ndir)->comment =
(char *)(&((struct smbc_dirent *)ndir)->name +
dirent->namelen +
1);
struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
DEBUG(4, ("smbc_mkdir(%s)\n", fname));
if (SMBC_parse_path(frame,
- context,
- fname,
- &workgroup,
- &server,
- &share,
- &path,
- &user,
- &password,
- NULL)) {
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
if (!user || user[0] == (char)0) {
- user = talloc_strdup(frame, context->user);
+ user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
errno = ENOMEM;
TALLOC_FREE(frame);
/*d_printf(">>>mkdir: resolving %s\n", path);*/
if (!cli_resolve_path(frame, "", srv->cli, path,
- &targetcli, &targetpath)) {
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
TALLOC_FREE(frame);
return -1;
TALLOC_FREE(frame);
return -1;
- }
+ }
TALLOC_FREE(frame);
return 0;
* Our list function simply checks to see if a directory is not empty
*/
-static int smbc_rmdir_dirempty = True;
-
static void
rmdir_list_fn(const char *mnt,
file_info *finfo,
{
if (strncmp(finfo->name, ".", 1) != 0 &&
strncmp(finfo->name, "..", 2) != 0) {
- smbc_rmdir_dirempty = False;
+ bool *smbc_rmdir_dirempty = (bool *)state;
+ *smbc_rmdir_dirempty = false;
}
}
struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
DEBUG(4, ("smbc_rmdir(%s)\n", fname));
if (SMBC_parse_path(frame,
- context,
- fname,
- &workgroup,
- &server,
- &share,
- &path,
- &user,
- &password,
- NULL)) {
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
if (!user || user[0] == (char)0) {
- user = talloc_strdup(frame, context->user);
+ user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
errno = ENOMEM;
TALLOC_FREE(frame);
/*d_printf(">>>rmdir: resolving %s\n", path);*/
if (!cli_resolve_path(frame, "", srv->cli, path,
- &targetcli, &targetpath)) {
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
TALLOC_FREE(frame);
return -1;
/* Local storage to avoid buffer overflows */
char *lpath;
-
- smbc_rmdir_dirempty = True; /* Make this so ... */
+ bool smbc_rmdir_dirempty = true;
lpath = talloc_asprintf(frame, "%s\\*",
targetpath);
if (cli_list(targetcli, lpath,
aDIR | aSYSTEM | aHIDDEN,
- rmdir_list_fn, NULL) < 0) {
+ rmdir_list_fn,
+ &smbc_rmdir_dirempty) < 0) {
/* Fix errno to ignore latest error ... */
DEBUG(5, ("smbc_rmdir: "
TALLOC_FREE(frame);
return -1;
- }
+ }
TALLOC_FREE(frame);
return 0;
{
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
TALLOC_FREE(frame);
}
- if (!dir || !SMBC_dlist_contains(context->files, dir)) {
+ if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
errno = EBADF;
TALLOC_FREE(frame);
*/
static struct smbc_dir_list *
-check_dir_ent(struct smbc_dir_list *list,
- struct smbc_dirent *dirent)
+check_dir_ent(struct smbc_dir_list *list,
+ struct smbc_dirent *dirent)
{
/* Run down the list looking for what we want */
struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL;
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
TALLOC_FREE(frame);
struct stat *st)
{
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL;
return -1;
uint16 mode;
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL; /* Best I can think of ... */
TALLOC_FREE(frame);
DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
if (SMBC_parse_path(frame,
- context,
- fname,
- &workgroup,
- &server,
- &share,
- &path,
- &user,
- &password,
- NULL)) {
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
if (!user || user[0] == (char)0) {
- user = talloc_strdup(frame, context->user);
+ user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
errno = ENOMEM;
TALLOC_FREE(frame);
time_t write_time;
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL; /* Best I can think of ... */
TALLOC_FREE(frame);
}
if (SMBC_parse_path(frame,
- context,
- fname,
- &workgroup,
- &server,
- &share,
- &path,
- &user,
- &password,
- NULL)) {
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
if (!user || user[0] == (char)0) {
- user = talloc_strdup(frame, context->user);
+ user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
errno = ENOMEM;
TALLOC_FREE(frame);
SMBC_unlink_ctx(SMBCCTX *context,
const char *fname)
{
- char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL;
+ 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;
TALLOC_CTX *frame = talloc_stackframe();
- if (!context || !context->initialized) {
+ if (!context || !context->internal->initialized) {
errno = EINVAL; /* Best I can think of ... */
TALLOC_FREE(frame);
}
if (SMBC_parse_path(frame,
- context,
- fname,
- &workgroup,
- &server,
- &share,
- &path,
- &user,
- &password,
- NULL)) {
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
if (!user || user[0] == (char)0) {
- user = talloc_strdup(frame, context->user);
+ user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
errno = ENOMEM;
TALLOC_FREE(frame);
/*d_printf(">>>unlink: resolving %s\n", path);*/
if (!cli_resolve_path(frame, "", srv->cli, path,
- &targetcli, &targetpath)) {
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
TALLOC_FREE(frame);
return -1;
int
SMBC_rename_ctx(SMBCCTX *ocontext,
- const char *oname,
+ const char *oname,
SMBCCTX *ncontext,
const char *nname)
{
TALLOC_CTX *frame = talloc_stackframe();
if (!ocontext || !ncontext ||
- !ocontext->initialized ||
- !ncontext->initialized) {
-
+ !ocontext->internal->initialized ||
+ !ncontext->internal->initialized) {
+
errno = EINVAL; /* Best I can think of ... */
TALLOC_FREE(frame);
return -1;
DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
if (SMBC_parse_path(frame,
- ocontext,
- oname,
- &workgroup,
- &server1,
- &share1,
- &path1,
- &user1,
- &password1,
- NULL)) {
+ ocontext,
+ oname,
+ &workgroup,
+ &server1,
+ &share1,
+ &path1,
+ &user1,
+ &password1,
+ NULL)) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
if (!user1 || user1[0] == (char)0) {
- user1 = talloc_strdup(frame, ocontext->user);
+ user1 = talloc_strdup(frame, smbc_getUser(ocontext));
if (!user1) {
errno = ENOMEM;
TALLOC_FREE(frame);
}
if (SMBC_parse_path(frame,
- ncontext,
- nname,
- NULL,
- &server2,
- &share2,
- &path2,
- &user2,
- &password2,
- NULL)) {
+ ncontext,
+ nname,
+ NULL,
+ &server2,
+ &share2,
+ &path2,
+ &user2,
+ &password2,
+ NULL)) {
errno = EINVAL;
TALLOC_FREE(frame);
return -1;
}
if (!user2 || user2[0] == (char)0) {
- user2 = talloc_strdup(frame, ncontext->user);
+ user2 = talloc_strdup(frame, smbc_getUser(ncontext));
if (!user2) {
errno = ENOMEM;
TALLOC_FREE(frame);
/*d_printf(">>>rename: resolving %s\n", path1);*/
if (!cli_resolve_path(frame, "", srv->cli, path1,
- &targetcli1, &targetpath1)) {
+ &targetcli1, &targetpath1)) {
d_printf("Could not resolve %s\n", path1);
TALLOC_FREE(frame);
return -1;
/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
/*d_printf(">>>rename: resolving %s\n", path2);*/
if (!cli_resolve_path(frame, "", srv->cli, path2,
- &targetcli2, &targetpath2)) {
+ &targetcli2, &targetpath2)) {
d_printf("Could not resolve %s\n", path2);
TALLOC_FREE(frame);
return -1;