*/
#include "includes.h"
+#include "libsmb/libsmb.h"
+#include "auth_info.h"
#include "libsmbclient.h"
#include "libsmb_internal.h"
-
+#include "rpc_client/cli_pipe.h"
+#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
+#include "libsmb/nmblib.h"
+#include "../libcli/smb/smbXcli_base.h"
/*
* Routine to open a directory
dirent_type = dir->dir_type;
if (add_dirent(dir, name, comment, dirent_type) < 0) {
-
/* An error occurred, what do we do? */
/* FIXME: Add some code here */
+ /* Change cli_NetServerEnum to take a fn
+ returning NTSTATUS... JRA. */
}
/* Point to the one just added */
}
if (add_dirent(dir, name, comment, dirent_type) < 0) {
-
/* An error occurred, what do we do? */
/* FIXME: Add some code here */
-
+ /* Change cli_NetServerEnum to take a fn
+ returning NTSTATUS... JRA. */
}
}
-static void
+static NTSTATUS
dir_list_fn(const char *mnt,
- file_info *finfo,
+ struct file_info *finfo,
const char *mask,
void *state)
{
if (add_dirent((SMBCFILE *)state, finfo->name, "",
- (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) {
-
- /* Handle an error ... */
-
- /* FIXME: Add some code ... */
-
+ (finfo->mode&FILE_ATTRIBUTE_DIRECTORY?SMBC_DIR:SMBC_FILE)) < 0) {
+ SMBCFILE *dir = (SMBCFILE *)state;
+ return map_nt_error_from_unix(dir->dir_error);
}
-
+ return NT_STATUS_OK;
}
static int
struct srvsvc_NetShareCtr1 ctr1;
fstring name = "";
fstring comment = "";
- struct rpc_pipe_client *pipe_hnd;
+ struct rpc_pipe_client *pipe_hnd = NULL;
NTSTATUS nt_status;
uint32_t resume_handle = 0;
uint32_t total_entries = 0;
+ struct dcerpc_binding_handle *b;
/* Open the server service pipe */
nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id,
info_ctr.level = 1;
info_ctr.ctr.ctr1 = &ctr1;
+ b = pipe_hnd->binding_handle;
+
/* Issue the NetShareEnum RPC call and retrieve the response */
- nt_status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, talloc_tos(),
+ nt_status = dcerpc_srvsvc_NetShareEnumAll(b, talloc_tos(),
pipe_hnd->desthost,
&info_ctr,
preferred_len,
&result);
/* Was it successful? */
- if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result) ||
- total_entries == 0) {
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ /* Nope. Go clean up. */
+ result = ntstatus_to_werror(nt_status);
+ goto done;
+ }
+
+ if (!W_ERROR_IS_OK(result)) {
/* Nope. Go clean up. */
goto done;
}
+ if (total_entries == 0) {
+ /* Nope. Go clean up. */
+ result = WERR_GENERAL_FAILURE;
+ goto done;
+ }
+
/* For each returned entry... */
- for (i = 0; i < total_entries; i++) {
+ for (i = 0; i < info_ctr.ctr.ctr1->count; i++) {
/* pull out the share name */
fstrcpy(name, info_ctr.ctr.ctr1->array[i].name);
if (!context || !context->internal->initialized) {
DEBUG(4, ("no valid context\n"));
- errno = EINVAL + 8192;
TALLOC_FREE(frame);
+ errno = EINVAL + 8192;
return NULL;
}
if (!fname) {
DEBUG(4, ("no valid fname\n"));
- errno = EINVAL + 8193;
TALLOC_FREE(frame);
+ errno = EINVAL + 8193;
return NULL;
}
&password,
&options)) {
DEBUG(4, ("no valid path\n"));
- errno = EINVAL + 8194;
TALLOC_FREE(frame);
+ errno = EINVAL + 8194;
return NULL;
}
/* Ensure the options are valid */
if (SMBC_check_options(server, share, path, options)) {
DEBUG(4, ("unacceptable options (%s)\n", options));
- errno = EINVAL + 8195;
TALLOC_FREE(frame);
+ errno = EINVAL + 8195;
return NULL;
}
if (!user || user[0] == (char)0) {
user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
- errno = ENOMEM;
TALLOC_FREE(frame);
+ errno = ENOMEM;
return NULL;
}
}
dir = SMB_MALLOC_P(SMBCFILE);
if (!dir) {
- errno = ENOMEM;
TALLOC_FREE(frame);
+ errno = ENOMEM;
return NULL;
}
int i;
int count;
int max_lmb_count;
- struct ip_service *ip_list;
- struct ip_service server_addr;
+ struct sockaddr_storage *ip_list;
+ struct sockaddr_storage server_addr;
struct user_auth_info u_info;
+ NTSTATUS status;
if (share[0] != (char)0 || path[0] != (char)0) {
- errno = EINVAL + 8196;
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
TALLOC_FREE(frame);
+ errno = EINVAL + 8196;
return NULL;
}
*/
ip_list = NULL;
- if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
- &count)))
+ status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
+ &ip_list, &count);
+ if (!NT_STATUS_IS_OK(status))
{
- SAFE_FREE(ip_list);
+ TALLOC_FREE(ip_list);
- if (!find_master_ip(workgroup, &server_addr.ss)) {
+ if (!find_master_ip(workgroup, &server_addr)) {
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
- errno = ENOENT;
TALLOC_FREE(frame);
+ errno = ENOENT;
return NULL;
}
- ip_list = (struct ip_service *)memdup(
- &server_addr, sizeof(server_addr));
+ ip_list = (struct sockaddr_storage *)talloc_memdup(
+ talloc_tos(), &server_addr,
+ sizeof(server_addr));
if (ip_list == NULL) {
- errno = ENOMEM;
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
TALLOC_FREE(frame);
+ errno = ENOMEM;
return NULL;
}
count = 1;
char *wg_ptr = NULL;
struct cli_state *cli = NULL;
- print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
+ print_sockaddr(addr, sizeof(addr), &ip_list[i]);
DEBUG(99, ("Found master browser %d of %d: %s\n",
i+1, MAX(count, max_lmb_count),
addr));
}
workgroup = talloc_strdup(frame, wg_ptr);
- server = talloc_strdup(frame, cli->desthost);
+ server = talloc_strdup(frame, smbXcli_conn_remote_name(cli->conn));
cli_shutdown(cli);
if (!workgroup || !server) {
- errno = ENOMEM;
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
TALLOC_FREE(frame);
+ errno = ENOMEM;
return NULL;
}
}
}
- SAFE_FREE(ip_list);
+ TALLOC_FREE(ip_list);
} else {
/*
* Server not an empty string ... Check the rest and see what
if (*path != '\0') {
/* Should not have empty share with path */
- errno = EINVAL + 8197;
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
TALLOC_FREE(frame);
+ errno = EINVAL + 8197;
return NULL;
}
*/
if (!srv &&
!is_ipaddress(server) &&
- (resolve_name(server, &rem_ss, 0x1d) || /* LMB */
- resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */
-
+ (resolve_name(server, &rem_ss, 0x1d, false) || /* LMB */
+ resolve_name(server, &rem_ss, 0x1b, false) )) { /* DMB */
+ /*
+ * "server" is actually a workgroup name,
+ * not a server. Make this clear.
+ */
+ char *wgroup = server;
fstring buserver;
dir->dir_type = SMBC_SERVER;
/*
* Get the backup list ...
*/
- if (!name_status_find(server, 0, 0,
+ if (!name_status_find(wgroup, 0, 0,
&rem_ss, buserver)) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &rem_ss);
DEBUG(0,("Could not get name of "
- "local/domain master browser "
- "for server %s\n", server));
+ "local/domain master browser "
+ "for workgroup %s from "
+ "address %s\n",
+ wgroup,
+ addr));
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
- errno = EPERM;
TALLOC_FREE(frame);
+ errno = EPERM;
return NULL;
}
dir->srv = srv;
/* Now, list the servers ... */
- if (!cli_NetServerEnum(srv->cli, server,
+ if (!cli_NetServerEnum(srv->cli, wgroup,
0x0000FFFE, list_fn,
(void *)dir)) {
return NULL;
}
} else if (srv ||
- (resolve_name(server, &rem_ss, 0x20))) {
+ (resolve_name(server, &rem_ss, 0x20, false))) {
/*
* If we hadn't found the server, get one now
*/
char *targetpath;
struct cli_state *targetcli;
+ NTSTATUS status;
/* We connect to the server and list the directory */
dir->dir_type = SMBC_FILE_SHARE;
return NULL;
}
- if (!cli_resolve_path(frame, "", context->internal->auth_info,
- srv->cli, path,
- &targetcli, &targetpath)) {
+ status = cli_resolve_path(
+ frame, "", context->internal->auth_info,
+ srv->cli, path, &targetcli, &targetpath);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Could not resolve %s\n", path);
if (dir) {
SAFE_FREE(dir->fname);
return NULL;
}
- if (cli_list(targetcli, targetpath,
- aDIR | aSYSTEM | aHIDDEN,
- dir_list_fn, (void *)dir) < 0) {
-
+ status = cli_list(targetcli, targetpath,
+ FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
+ dir_list_fn, (void *)dir);
+ if (!NT_STATUS_IS_OK(status)) {
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
}
- errno = saved_errno;
TALLOC_FREE(frame);
+ errno = saved_errno;
return NULL;
}
}
while ((dirlist = dir->dir_next)) {
struct smbc_dirent *dirent;
+ struct smbc_dirent *currentEntry = (struct smbc_dirent *)ndir;
if (!dirlist->dirent) {
}
- memcpy(ndir, dirent, reqd); /* Copy the data in ... */
+ memcpy(currentEntry, dirent, reqd); /* Copy the data in ... */
- ((struct smbc_dirent *)ndir)->comment =
- (char *)(&((struct smbc_dirent *)ndir)->name +
- dirent->namelen +
- 1);
+ currentEntry->comment = ¤tEntry->name[0] +
+ dirent->namelen + 1;
ndir += reqd;
-
rem -= reqd;
+ /* Try and align the struct for the next entry
+ on a valid pointer boundary by appending zeros */
+ while((rem > 0) && ((unsigned long long)ndir & (sizeof(void*) - 1))) {
+ *ndir = '\0';
+ rem--;
+ ndir++;
+ currentEntry->dirlen++;
+ }
+
dir->dir_next = dirlist = dirlist -> next;
}
char *targetpath = NULL;
struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
if (!context || !context->internal->initialized) {
errno = EINVAL;
}
/*d_printf(">>>mkdir: resolving %s\n", path);*/
- if (!cli_resolve_path(frame, "", context->internal->auth_info,
- srv->cli, path,
- &targetcli, &targetpath)) {
+ status = cli_resolve_path(frame, "", context->internal->auth_info,
+ srv->cli, path, &targetcli, &targetpath);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Could not resolve %s\n", path);
errno = ENOENT;
TALLOC_FREE(frame);
* Our list function simply checks to see if a directory is not empty
*/
-static void
+static NTSTATUS
rmdir_list_fn(const char *mnt,
- file_info *finfo,
+ struct file_info *finfo,
const char *mask,
void *state)
{
bool *smbc_rmdir_dirempty = (bool *)state;
*smbc_rmdir_dirempty = false;
}
+ return NT_STATUS_OK;
}
/*
char *targetpath = NULL;
struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
if (!context || !context->internal->initialized) {
errno = EINVAL;
}
/*d_printf(">>>rmdir: resolving %s\n", path);*/
- if (!cli_resolve_path(frame, "", context->internal->auth_info,
- srv->cli, path,
- &targetcli, &targetpath)) {
+ status = cli_resolve_path(frame, "", context->internal->auth_info,
+ srv->cli, path, &targetcli, &targetpath);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Could not resolve %s\n", path);
errno = ENOENT;
TALLOC_FREE(frame);
return -1;
}
- if (cli_list(targetcli, lpath,
- aDIR | aSYSTEM | aHIDDEN,
- rmdir_list_fn,
- &smbc_rmdir_dirempty) < 0) {
+ status = cli_list(targetcli, lpath,
+ FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
+ rmdir_list_fn,
+ &smbc_rmdir_dirempty);
+ if (!NT_STATUS_IS_OK(status)) {
/* Fix errno to ignore latest error ... */
DEBUG(5, ("smbc_rmdir: "
"cli_list returned an error: %d\n",
char *path = NULL;
uint16 mode;
TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
if (!context || !context->internal->initialized) {
}
/*d_printf(">>>unlink: resolving %s\n", path);*/
- if (!cli_resolve_path(frame, "", context->internal->auth_info,
- srv->cli, path,
- &targetcli, &targetpath)) {
+ status = cli_resolve_path(frame, "", context->internal->auth_info,
+ srv->cli, path, &targetcli, &targetpath);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Could not resolve %s\n", path);
errno = ENOENT;
TALLOC_FREE(frame);
mode = 0;
- if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;
- if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;
- if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
- if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
+ if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= FILE_ATTRIBUTE_READONLY;
+ if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= FILE_ATTRIBUTE_ARCHIVE;
+ if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= FILE_ATTRIBUTE_SYSTEM;
+ if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= FILE_ATTRIBUTE_HIDDEN;
if (!NT_STATUS_IS_OK(cli_setatr(targetcli, targetpath, mode, 0))) {
errno = SMBC_errno(context, targetcli);
struct cli_state *targetcli = NULL;
SMBCSRV *srv = NULL;
TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
if (!context || !context->internal->initialized) {
}
/*d_printf(">>>unlink: resolving %s\n", path);*/
- if (!cli_resolve_path(frame, "", context->internal->auth_info,
- srv->cli, path,
- &targetcli, &targetpath)) {
+ status = cli_resolve_path(frame, "", context->internal->auth_info,
+ srv->cli, path, &targetcli, &targetpath);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Could not resolve %s\n", path);
errno = ENOENT;
TALLOC_FREE(frame);
}
/*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/
- if (!NT_STATUS_IS_OK(cli_unlink(targetcli, targetpath, aSYSTEM | aHIDDEN))) {
+ if (!NT_STATUS_IS_OK(cli_unlink(targetcli, targetpath, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
errno = SMBC_errno(context, targetcli);
if (errno == EACCES) { /* Check if the file is a directory */
int saverr = errno;
- SMB_OFF_T size = 0;
+ off_t size = 0;
uint16 mode = 0;
struct timespec write_time_ts;
struct timespec access_time_ts;
struct cli_state *targetcli2 = NULL;
SMBCSRV *srv = NULL;
TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
if (!ocontext || !ncontext ||
!ocontext->internal->initialized ||
password1);
/*d_printf(">>>rename: resolving %s\n", path1);*/
- if (!cli_resolve_path(frame, "", ocontext->internal->auth_info,
- srv->cli,
- path1,
- &targetcli1, &targetpath1)) {
+ status = cli_resolve_path(frame, "", ocontext->internal->auth_info,
+ srv->cli, path1, &targetcli1, &targetpath1);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Could not resolve %s\n", path1);
errno = ENOENT;
TALLOC_FREE(frame);
/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
/*d_printf(">>>rename: resolving %s\n", path2);*/
- if (!cli_resolve_path(frame, "", ncontext->internal->auth_info,
- srv->cli,
- path2,
- &targetcli2, &targetpath2)) {
+ status = cli_resolve_path(frame, "", ncontext->internal->auth_info,
+ srv->cli, path2, &targetcli2, &targetpath2);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Could not resolve %s\n", path2);
errno = ENOENT;
TALLOC_FREE(frame);
}
/*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/
- if (strcmp(targetcli1->desthost, targetcli2->desthost) ||
+ if (strcmp(smbXcli_conn_remote_name(targetcli1->conn), smbXcli_conn_remote_name(targetcli2->conn)) ||
strcmp(targetcli1->share, targetcli2->share))
{
/* can't rename across file systems */
int eno = SMBC_errno(ocontext, targetcli1);
if (eno != EEXIST ||
- !NT_STATUS_IS_OK(cli_unlink(targetcli1, targetpath2, aSYSTEM | aHIDDEN)) ||
+ !NT_STATUS_IS_OK(cli_unlink(targetcli1, targetpath2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) ||
!NT_STATUS_IS_OK(cli_rename(targetcli1, targetpath1, targetpath2))) {
errno = eno;