Copyright (C) John Terpstra 2000
Copyright (C) Tom Jansen (Ninja ISD) 2002
Copyright (C) Derrell Lipman 2003, 2004
+ 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
off_t offset,
int whence);
-extern BOOL in_client;
+extern bool in_client;
/*
* Is the logging working / configfile read ?
/*
* smbc_urldecode()
+ * and smbc_urldecode_talloc() (internal fn.)
*
* Convert strings of %xx to their single character equivalent. Each 'x' must
* be a valid hexadecimal digit, or that % sequence is left undecoded.
* Returns the number of % sequences which could not be converted due to lack
* of two following hexadecimal digits.
*/
-int
-smbc_urldecode(char *dest, char * src, size_t max_dest_len)
+static int
+smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src)
{
- int old_length = strlen(src);
- int i = 0;
- int err_count = 0;
- pstring temp;
- char * p;
+ int old_length = strlen(src);
+ int i = 0;
+ int err_count = 0;
+ size_t newlen = 1;
+ char *p, *dest;
- if ( old_length == 0 ) {
- return 0;
- }
+ 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 */
+ character = (a * 16) + b;
+ if (character == '\0') {
+ break; /* Stop at %00 */
+ }
+ i += 2;
+ } else {
+ err_count++;
+ }
+ }
+ newlen++;
+ }
+
+ dest = TALLOC_ARRAY(ctx, char, newlen);
+ if (!dest) {
+ return err_count;
+ }
- p = temp;
- while ( i < old_length ) {
- unsigned char character = src[ i++ ];
+ 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;
+ 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 */
character = (a * 16) + b;
-
if (character == '\0') {
break; /* Stop at %00 */
}
-
i += 2;
} else {
-
err_count++;
}
}
-
*p++ = character;
}
*p = '\0';
+ *pp_dest = dest;
+ return err_count;
+}
- strncpy(dest, temp, max_dest_len - 1);
- dest[max_dest_len - 1] = '\0';
+int
+smbc_urldecode(char *dest, char *src, size_t max_dest_len)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *pdest;
+ int ret = smbc_urldecode_talloc(frame, &pdest, src);
- return err_count;
+ if (pdest) {
+ strlcpy(dest, pdest, max_dest_len);
+ }
+ TALLOC_FREE(frame);
+ return ret;
}
/*
* Returns the remaining buffer length.
*/
int
-smbc_urlencode(char * dest, char * src, int max_dest_len)
+smbc_urlencode(char *dest, char *src, int max_dest_len)
{
char hex[] = "0123456789ABCDEF";
*dest++ = '\0';
max_dest_len--;
-
+
return max_dest_len;
}
static const char *smbc_prefix = "smb:";
static int
-smbc_parse_path(SMBCCTX *context,
+smbc_parse_path(TALLOC_CTX *ctx,
+ SMBCCTX *context,
const char *fname,
- char *workgroup, int workgroup_len,
- char *server, int server_len,
- char *share, int share_len,
- char *path, int path_len,
- char *user, int user_len,
- char *password, int password_len,
- char *options, int options_len)
+ char **pp_workgroup,
+ char **pp_server,
+ char **pp_share,
+ char **pp_path,
+ char **pp_user,
+ char **pp_password,
+ char **pp_options)
{
- static pstring s;
- pstring userinfo;
+ char *s;
const char *p;
char *q, *r;
int len;
- server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
+ /* 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.
*/
- if (workgroup != NULL) {
- strncpy(workgroup, context->workgroup, workgroup_len - 1);
- workgroup[workgroup_len - 1] = '\0';
- }
+ if (pp_workgroup != NULL) {
+ *pp_workgroup = talloc_strdup(ctx, context->workgroup);
+ }
- if (options != NULL && options_len > 0) {
- options[0] = (char)0;
- }
- pstrcpy(s, fname);
+ if (pp_options) {
+ *pp_options = talloc_strdup(ctx, "");
+ }
+ s = talloc_strdup(ctx, fname);
/* see if it has the right prefix */
len = strlen(smbc_prefix);
/* 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 */
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 (options != NULL && options_len > 0) {
- safe_strcpy(options, q, options_len - 1);
- }
- }
+ /* Copy the options */
+ if (*pp_options != NULL) {
+ TALLOC_FREE(*pp_options);
+ *pp_options = talloc_strdup(ctx, q);
+ }
+ }
- if (*p == (char)0)
- goto decoding;
+ if (*p == '\0') {
+ goto decoding;
+ }
if (*p == '/') {
int wl = strlen(context->workgroup);
wl = 16;
}
- strncpy(server, context->workgroup, wl);
- server[wl] = '\0';
+ *pp_server = talloc_strdup(ctx, context->workgroup);
+ if (!*pp_server) {
+ return -1;
+ }
+ *pp_server[wl] = '\0';
return 0;
}
/*
- * ok, its for us. Now parse out the server, share etc.
+ * ok, its for us. Now parse out the server, share etc.
*
* However, we want to parse out [[domain;]user[:password]@] if it
* exists ...
q = strchr_m(p, '@');
r = strchr_m(p, '/');
if (q && (!r || q < r)) {
- pstring username, passwd, domain;
- const char *u = userinfo;
-
- next_token_no_ltrim(&p, userinfo, "@", sizeof(fstring));
+ char *userinfo = NULL;
+ const char *u;
- username[0] = passwd[0] = domain[0] = 0;
+ next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@");
+ if (!userinfo) {
+ return -1;
+ }
+ u = userinfo;
if (strchr_m(u, ';')) {
-
- next_token_no_ltrim(&u, domain, ";", sizeof(fstring));
-
+ char *workgroup;
+ next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
+ if (!workgroup) {
+ return -1;
+ }
+ if (pp_workgroup) {
+ *pp_workgroup = workgroup;
+ }
}
if (strchr_m(u, ':')) {
-
- next_token_no_ltrim(&u, username, ":", sizeof(fstring));
-
- pstrcpy(passwd, u);
-
- }
- else {
-
- pstrcpy(username, u);
-
+ next_token_no_ltrim_talloc(ctx, &u, pp_user, ":");
+ if (!*pp_user) {
+ return -1;
+ }
+ *pp_password = talloc_strdup(ctx, u);
+ if (!*pp_password) {
+ return -1;
+ }
+ } else {
+ *pp_user = talloc_strdup(ctx, u);
+ if (!*pp_user) {
+ return -1;
+ }
}
-
- if (domain[0] && workgroup) {
- strncpy(workgroup, domain, workgroup_len - 1);
- workgroup[workgroup_len - 1] = '\0';
- }
-
- if (username[0]) {
- strncpy(user, username, user_len - 1);
- user[user_len - 1] = '\0';
- }
-
- if (passwd[0]) {
- strncpy(password, passwd, password_len - 1);
- password[password_len - 1] = '\0';
- }
-
}
- if (!next_token(&p, server, "/", sizeof(fstring))) {
-
+ if (!next_token_talloc(ctx, &p, pp_server, "/")) {
return -1;
-
}
- if (*p == (char)0) goto decoding; /* That's it ... */
-
- if (!next_token(&p, share, "/", sizeof(fstring))) {
+ 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.
*/
- *path = '\0';
if (*p != '\0') {
- *path = '/';
- safe_strcpy(path + 1, p, path_len - 2);
- }
-
- all_string_sub(path, "/", "\\", 0);
+ *pp_path = talloc_asprintf(ctx,
+ "\\%s",
+ p);
+ } else {
+ *pp_path = talloc_strdup(ctx, "");
+ }
+ if (!*pp_path) {
+ return -1;
+ }
+ string_replace(*pp_path, '/', '\\');
decoding:
- (void) smbc_urldecode(path, path, path_len);
- (void) smbc_urldecode(server, server, server_len);
- (void) smbc_urldecode(share, share, share_len);
- (void) smbc_urldecode(user, user, user_len);
- (void) smbc_urldecode(password, password, password_len);
+
+ (void) smbc_urldecode_talloc(ctx, pp_path, *pp_path);
+ (void) smbc_urldecode_talloc(ctx, pp_server, *pp_server);
+ (void) smbc_urldecode_talloc(ctx, pp_share, *pp_share);
+ (void) smbc_urldecode_talloc(ctx, pp_user, *pp_user);
+ (void) smbc_urldecode_talloc(ctx, pp_password, *pp_password);
return 0;
}
socklen_t size;
struct sockaddr addr;
- /*
- * Although the use of port 139 is not a guarantee that we're using
- * netbios, we assume so. We don't want to send a keepalive packet if
- * not netbios because it's not valid, and Vista, at least,
- * disconnects the client on such a request.
- */
- if (server->cli->port == 139) {
- /* Assuming netbios. Send a keepalive packet */
- if ( send_keepalive(server->cli->fd) == False ) {
- return 1;
- }
- } else {
- /*
- * Assuming not netbios. Try a different method to detect if
- * the connection is still alive.
- */
- size = sizeof(addr);
- if (getpeername(server->cli->fd, &addr, &size) == -1) {
- return 1;
- }
- }
-
- /* connection is ok */
- return 0;
+ size = sizeof(addr);
+ return (getpeername(server->cli->fd, &addr, &size) == -1);
}
/*
if (file->srv == srv) {
/* Still used */
DEBUG(3, ("smbc_remove_usused_server: "
- "%p still used by %p.\n",
+ "%p still used by %p.\n",
srv, file));
return 1;
}
DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
- context->callbacks.remove_cached_srv_fn(context, srv);
+ (context->callbacks.remove_cached_srv_fn)(context, srv);
SAFE_FREE(srv);
-
return 0;
}
+/****************************************************************
+ * Call the auth_fn with fixed size (fstring) buffers.
+ ***************************************************************/
+
+static void call_auth_fn(TALLOC_CTX *ctx,
+ SMBCCTX *context,
+ const char *server,
+ const char *share,
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password)
+{
+ fstring workgroup;
+ fstring username;
+ fstring password;
+
+ strlcpy(workgroup, *pp_workgroup, sizeof(workgroup));
+ strlcpy(username, *pp_username, sizeof(username));
+ strlcpy(password, *pp_password, sizeof(password));
+
+ if (context->internal->_auth_fn_with_context != NULL) {
+ (context->internal->_auth_fn_with_context)(
+ context,
+ server, share,
+ workgroup, sizeof(workgroup),
+ username, sizeof(username),
+ password, sizeof(password));
+ } else {
+ (context->callbacks.auth_fn)(
+ server, share,
+ workgroup, sizeof(workgroup),
+ username, sizeof(username),
+ password, sizeof(password));
+ }
+
+ TALLOC_FREE(*pp_workgroup);
+ TALLOC_FREE(*pp_username);
+ TALLOC_FREE(*pp_password);
+
+ *pp_workgroup = talloc_strdup(ctx, workgroup);
+ *pp_username = talloc_strdup(ctx, username);
+ *pp_password = talloc_strdup(ctx, password);
+}
+
static SMBCSRV *
-find_server(SMBCCTX *context,
- const char *server,
- const char *share,
- fstring workgroup,
- fstring username,
- fstring password)
+find_server(TALLOC_CTX *ctx,
+ SMBCCTX *context,
+ const char *server,
+ const char *share,
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password)
{
SMBCSRV *srv;
int auth_called = 0;
-
+
check_server_cache:
- srv = context->callbacks.get_cached_srv_fn(context, server, share,
- workgroup, username);
-
- if (!auth_called && !srv && (!username[0] || !password[0])) {
- if (context->internal->_auth_fn_with_context != NULL) {
- context->internal->_auth_fn_with_context(
- context,
- server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- } else {
- context->callbacks.auth_fn(
- server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- }
+ srv = (context->callbacks.get_cached_srv_fn)(context, server, share,
+ *pp_workgroup, *pp_username);
+
+ if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] ||
+ !*pp_password || !(*pp_password)[0])) {
+ call_auth_fn(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
+
+ if (!pp_workgroup || !pp_username || !pp_password) {
+ return NULL;
+ }
/*
* However, smbc_auth_fn may have picked up info relating to
*/
auth_called = 1;
goto check_server_cache;
-
+
}
-
+
if (srv) {
- if (context->callbacks.check_server_fn(context, srv)) {
+ if ((context->callbacks.check_server_fn)(context, srv)) {
/*
- * This server is no good anymore
+ * This server is no good anymore
* Try to remove it and check for more possible
* servers in the cache
*/
- if (context->callbacks.remove_unused_server_fn(context,
- srv)) {
+ if ((context->callbacks.remove_unused_server_fn)(context,
+ srv)) {
/*
* We could not remove the server completely,
* remove it from the cache so we will not get
* it again. It will be removed when the last
* file/dir is closed.
*/
- context->callbacks.remove_cached_srv_fn(context,
- srv);
+ (context->callbacks.remove_cached_srv_fn)(context,
+ srv);
}
-
+
/*
* Maybe there are more cached connections to this
* server
*/
- goto check_server_cache;
+ goto check_server_cache;
}
return srv;
* Connect to a server, possibly on an existing connection
*
* Here, what we want to do is: If the server and username
- * match an existing connection, reuse that, otherwise, establish a
+ * match an existing connection, reuse that, otherwise, establish a
* new connection.
*
* If we have to create a new connection, call the auth_fn to get the
*/
static SMBCSRV *
-smbc_server(SMBCCTX *context,
- BOOL connect_if_not_found,
- const char *server,
- const char *share,
- fstring workgroup,
- fstring username,
- fstring password)
+smbc_server(TALLOC_CTX *ctx,
+ SMBCCTX *context,
+ bool connect_if_not_found,
+ const char *server,
+ const char *share,
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password)
{
SMBCSRV *srv=NULL;
struct cli_state *c;
struct nmb_name called, calling;
const char *server_n = server;
- pstring ipenv;
- struct in_addr ip;
+ struct sockaddr_storage ss;
int tried_reverse = 0;
int port_try_first;
int port_try_next;
const char *username_used;
NTSTATUS status;
- zero_ip(&ip);
+ zero_addr(&ss);
ZERO_STRUCT(c);
if (server[0] == 0) {
}
/* Look for a cached connection */
- srv = find_server(context, server, share,
- workgroup, username, password);
-
+ srv = find_server(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
+
/*
* If we found a connection and we're only allowed one share per
* server...
*/
if (srv->cli->cnum == (uint16) -1) {
/* Ensure we have accurate auth info */
- if (context->internal->_auth_fn_with_context != NULL) {
- context->internal->_auth_fn_with_context(
- context,
- server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- } else {
- context->callbacks.auth_fn(
- server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- }
+ call_auth_fn(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
+
+ if (!*pp_workgroup || !*pp_username || !*pp_password) {
+ errno = ENOMEM;
+ cli_shutdown(srv->cli);
+ srv->cli = NULL;
+ (context->callbacks.remove_cached_srv_fn)(context,
+ srv);
+ return NULL;
+ }
+
+ /*
+ * We don't need to renegotiate encryption
+ * here as the encryption context is not per
+ * tid.
+ */
+
+ if (!cli_send_tconX(srv->cli, share, "?????",
+ *pp_password,
+ strlen(*pp_password)+1)) {
- if (! cli_send_tconX(srv->cli, share, "?????",
- password, strlen(password)+1)) {
-
errno = smbc_errno(context, srv->cli);
cli_shutdown(srv->cli);
srv->cli = NULL;
- context->callbacks.remove_cached_srv_fn(context,
- srv);
+ (context->callbacks.remove_cached_srv_fn)(context,
+ srv);
srv = NULL;
}
}
}
}
-
+
/* If we have a connection... */
if (srv) {
return NULL;
}
+ if (!*pp_workgroup || !*pp_username || !*pp_password) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
make_nmb_name(&calling, context->netbios_name, 0x0);
make_nmb_name(&called , server, 0x20);
DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));
-
+
DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
again:
- slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
- zero_ip(&ip);
+ zero_addr(&ss);
/* have to open a new connection */
if ((c = cli_initialise()) == NULL) {
c->port = port_try_first;
- status = cli_connect(c, server_n, &ip);
+ status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
/* First connection attempt failed. Try alternate port. */
c->port = port_try_next;
- status = cli_connect(c, server_n, &ip);
+ status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(c);
errno = ETIMEDOUT;
if (is_ipaddress(server) && !tried_reverse) {
fstring remote_name;
- struct in_addr rem_ip;
+ struct sockaddr_storage rem_ss;
- if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) {
+ if (!interpret_string_addr(&rem_ss, server,
+ NI_NUMERICHOST)) {
DEBUG(4, ("Could not convert IP address "
- "%s to struct in_addr\n", server));
+ "%s to struct sockaddr_storage\n",
+ server));
errno = ETIMEDOUT;
return NULL;
}
tried_reverse++; /* Yuck */
- if (name_status_find("*", 0, 0, rem_ip, remote_name)) {
+ if (name_status_find("*", 0, 0, &rem_ss, remote_name)) {
make_nmb_name(&called, remote_name, 0x20);
goto again;
}
errno = ETIMEDOUT;
return NULL;
}
-
+
DEBUG(4,(" session request ok\n"));
-
+
if (!cli_negprot(c)) {
cli_shutdown(c);
errno = ETIMEDOUT;
return NULL;
}
- username_used = username;
+ username_used = *pp_username;
+
+ if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
+ *pp_password, strlen(*pp_password),
+ *pp_password, strlen(*pp_password),
+ *pp_workgroup))) {
- if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
- password, strlen(password),
- password, strlen(password),
- workgroup))) {
-
/* Failed. Try an anonymous login, if allowed by flags. */
username_used = "";
if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
- password, 1,
- password, 0,
- workgroup))) {
+ *pp_password, 1,
+ *pp_password, 0,
+ *pp_workgroup))) {
cli_shutdown(c);
errno = EPERM;
DEBUG(4,(" session setup ok\n"));
if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
+ *pp_password, strlen(*pp_password)+1)) {
errno = smbc_errno(context, c);
cli_shutdown(c);
return NULL;
}
-
+
DEBUG(4,(" tconx ok\n"));
-
+
+ if (context->internal->_smb_encryption_level) {
+ /* Attempt UNIX smb encryption. */
+ if (!NT_STATUS_IS_OK(cli_force_encryption(c,
+ username_used,
+ *pp_password,
+ *pp_workgroup))) {
+
+ /*
+ * context->internal->_smb_encryption_level == 1
+ * means don't fail if encryption can't be negotiated,
+ * == 2 means fail if encryption can't be negotiated.
+ */
+
+ DEBUG(4,(" SMB encrypt failed\n"));
+
+ if (context->internal->_smb_encryption_level == 2) {
+ cli_shutdown(c);
+ errno = EPERM;
+ return NULL;
+ }
+ }
+ DEBUG(4,(" SMB encrypt ok\n"));
+ }
+
/*
* Ok, we have got a nice connection
* Let's allocate a server structure.
/* now add it to the cache (internal or external) */
/* Let the cache function set errno if it wants to */
errno = 0;
- if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) {
+ if ((context->callbacks.add_cached_srv_fn)(context, srv,
+ server, share,
+ *pp_workgroup,
+ *pp_username)) {
int saved_errno = errno;
DEBUG(3, (" Failed to add server to cache\n"));
errno = saved_errno;
}
goto failed;
}
-
- DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
+
+ DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
server, share, srv));
DLIST_ADD(context->internal->_servers, srv);
if (!srv) {
return NULL;
}
-
+
SAFE_FREE(srv);
return NULL;
}
* connection. This works similarly to smbc_server().
*/
static SMBCSRV *
-smbc_attr_server(SMBCCTX *context,
- const char *server,
- const char *share,
- fstring workgroup,
- fstring username,
- fstring password,
- POLICY_HND *pol)
+smbc_attr_server(TALLOC_CTX *ctx,
+ SMBCCTX *context,
+ const char *server,
+ const char *share,
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password,
+ POLICY_HND *pol)
{
int flags;
- struct in_addr ip;
+ struct sockaddr_storage ss;
struct cli_state *ipc_cli;
struct rpc_pipe_client *pipe_hnd;
NTSTATUS nt_status;
* our "special" share name '*IPC$', which is an impossible real share
* name due to the leading asterisk.
*/
- ipc_srv = find_server(context, server, "*IPC$",
- workgroup, username, password);
+ ipc_srv = find_server(ctx, context, server, "*IPC$",
+ pp_workgroup, pp_username, pp_password);
if (!ipc_srv) {
/* We didn't find a cached connection. Get the password */
- if (*password == '\0') {
+ if (!*pp_password || (*pp_password)[0] == '\0') {
/* ... then retrieve it now. */
- if (context->internal->_auth_fn_with_context != NULL) {
- context->internal->_auth_fn_with_context(
- context,
- server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- } else {
- context->callbacks.auth_fn(
- server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- }
+ call_auth_fn(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
+ if (!*pp_workgroup || !*pp_username || !*pp_password) {
+ errno = ENOMEM;
+ return NULL;
+ }
}
-
+
flags = 0;
if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) {
flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
}
- zero_ip(&ip);
+ zero_addr(&ss);
nt_status = cli_full_connection(&ipc_cli,
- global_myname(), server,
- &ip, 0, "IPC$", "?????",
- username, workgroup,
- password, flags,
- Undefined, NULL);
+ global_myname(), server,
+ &ss, 0, "IPC$", "?????",
+ *pp_username,
+ *pp_workgroup,
+ *pp_password,
+ flags,
+ Undefined, NULL);
if (! NT_STATUS_IS_OK(nt_status)) {
DEBUG(1,("cli_full_connection failed! (%s)\n",
nt_errstr(nt_status)));
return NULL;
}
+ if (context->internal->_smb_encryption_level) {
+ /* Attempt UNIX smb encryption. */
+ if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli,
+ *pp_username,
+ *pp_password,
+ *pp_workgroup))) {
+
+ /*
+ * context->internal->_smb_encryption_level == 1
+ * means don't fail if encryption can't be negotiated,
+ * == 2 means fail if encryption can't be negotiated.
+ */
+
+ DEBUG(4,(" SMB encrypt failed on IPC$\n"));
+
+ if (context->internal->_smb_encryption_level == 2) {
+ cli_shutdown(ipc_cli);
+ errno = EPERM;
+ return NULL;
+ }
+ }
+ DEBUG(4,(" SMB encrypt ok on IPC$\n"));
+ }
+
ipc_srv = SMB_MALLOC_P(SMBCSRV);
if (!ipc_srv) {
errno = ENOMEM;
* SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000
* so we might as well do it too.
*/
-
+
nt_status = rpccli_lsa_open_policy(
pipe_hnd,
- ipc_srv->cli->mem_ctx,
- True,
+ talloc_tos(),
+ True,
GENERIC_EXECUTE_ACCESS,
pol);
-
+
if (!NT_STATUS_IS_OK(nt_status)) {
errno = smbc_errno(context, ipc_srv->cli);
cli_shutdown(ipc_srv->cli);
/* now add it to the cache (internal or external) */
errno = 0; /* let cache function set errno if it likes */
- if (context->callbacks.add_cached_srv_fn(context, ipc_srv,
- server,
- "*IPC$",
- workgroup,
- username)) {
+ if ((context->callbacks.add_cached_srv_fn)(context, ipc_srv,
+ server,
+ "*IPC$",
+ *pp_workgroup,
+ *pp_username)) {
DEBUG(3, (" Failed to add server to cache\n"));
if (errno == 0) {
errno = ENOMEM;
int flags,
mode_t mode)
{
- fstring server, share, user, password, workgroup;
- pstring path;
- pstring targetpath;
- struct cli_state *targetcli;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
SMBCSRV *srv = NULL;
SMBCFILE *file = NULL;
int fd;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return NULL;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return NULL;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ 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] == '\\') {
-
fd = -1;
-
- }
- else {
-
+ } 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( "", srv->cli, path, &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
SAFE_FREE(file);
+ TALLOC_FREE(frame);
return NULL;
}
/*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/
-
+
if ((fd = cli_open(targetcli, targetpath, flags,
context->internal->_share_mode)) < 0) {
SAFE_FREE(file);
errno = smbc_errno(context, targetcli);
+ TALLOC_FREE(frame);
return NULL;
}
if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) {
(void) smbc_close_ctx(context, file);
errno = ENXIO;
+ TALLOC_FREE(frame);
return NULL;
}
}
+ TALLOC_FREE(frame);
return file;
}
int eno = 0;
eno = smbc_errno(context, srv->cli);
- file = context->opendir(context, fname);
+ file = (context->opendir)(context, fname);
if (!file) errno = eno;
+ TALLOC_FREE(frame);
return file;
}
errno = EINVAL; /* FIXME, correct errno ? */
+ TALLOC_FREE(frame);
return NULL;
}
size_t count)
{
int ret;
- fstring server, share, user, password;
- pstring path, targetpath;
- struct cli_state *targetcli;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
/*
* offset:
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count));
if (!file || !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;
}
/*d_printf(">>>read: parsing %s\n", file->fname);*/
- if (smbc_parse_path(context, file->fname,
- NULL, 0,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ file->fname,
+ NULL,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
-
+
/*d_printf(">>>read: resolving %s\n", path);*/
- if (!cli_resolve_path("", file->srv->cli, path,
- &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", file->srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
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;
}
DEBUG(4, (" --> %d\n", ret));
+ TALLOC_FREE(frame);
return ret; /* Success, ret bytes of data ... */
}
{
int ret;
off_t offset;
- fstring server, share, user, password;
- pstring path, targetpath;
- struct cli_state *targetcli;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
/* First check all pointers before dereferencing them */
-
+
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
if (!file || !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(context, file->fname,
- NULL, 0,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ file->fname,
+ NULL,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
-
+
/*d_printf(">>>write: resolving %s\n", path);*/
- if (!cli_resolve_path("", file->srv->cli, path,
- &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", file->srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
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 ... */
}
-
+
/*
* Routine to close() a file ...
*/
smbc_close_ctx(SMBCCTX *context,
SMBCFILE *file)
{
- SMBCSRV *srv;
- fstring server, share, user, password;
- pstring path, targetpath;
- struct cli_state *targetcli;
+ SMBCSRV *srv;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
-
errno = EBADF;
+ TALLOC_FREE(frame);
return -1;
-
}
/* IS a dir ... */
if (!file->file) {
-
- return context->closedir(context, file);
-
+ TALLOC_FREE(frame);
+ return (context->closedir)(context, file);
}
/*d_printf(">>>close: parsing %s\n", file->fname);*/
- if (smbc_parse_path(context, file->fname,
- NULL, 0,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ file->fname,
+ NULL,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
-
+
/*d_printf(">>>close: resolving %s\n", path);*/
- if (!cli_resolve_path("", file->srv->cli, path,
- &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", file->srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
return -1;
}
/*d_printf(">>>close: resolved path as %s\n", targetpath);*/
DLIST_REMOVE(context->internal->_files, file);
SAFE_FREE(file->fname);
SAFE_FREE(file);
- context->callbacks.remove_unused_server_fn(context, srv);
-
+ (context->callbacks.remove_unused_server_fn)(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;
}
* Get info from an SMB server on a file. Use a qpathinfo call first
* and if that fails, use getatr, as Win95 sometimes refuses qpathinfo
*/
-static BOOL
+static bool
smbc_getatr(SMBCCTX * context,
SMBCSRV *srv,
- char *path,
+ char *path,
uint16 *mode,
- SMB_OFF_T *size,
+ SMB_OFF_T *size,
struct timespec *create_time_ts,
struct timespec *access_time_ts,
struct timespec *write_time_ts,
struct timespec *change_time_ts,
SMB_INO_T *ino)
{
- pstring fixedpath;
- pstring targetpath;
- struct cli_state *targetcli;
+ char *fixedpath = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
time_t write_time;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
/* path fixup for . and .. */
- if (strequal(path, ".") || strequal(path, ".."))
- pstrcpy(fixedpath, "\\");
- else
- {
- pstrcpy(fixedpath, path);
+ if (strequal(path, ".") || strequal(path, "..")) {
+ fixedpath = talloc_strdup(frame, "\\");
+ if (!fixedpath) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ } else {
+ fixedpath = talloc_strdup(frame, path);
+ if (!fixedpath) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
trim_string(fixedpath, NULL, "\\..");
trim_string(fixedpath, NULL, "\\.");
}
DEBUG(4,("smbc_getatr: sending qpathinfo\n"));
-
- if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath))
- {
+
+ if (!cli_resolve_path(frame, "", srv->cli, fixedpath,
+ &targetcli, &targetpath)) {
d_printf("Couldn't resolve %s\n", path);
+ TALLOC_FREE(frame);
return False;
}
-
+
if (!srv->no_pathinfo2 &&
cli_qpathinfo2(targetcli, targetpath,
create_time_ts,
write_time_ts,
change_time_ts,
size, mode, ino)) {
- return True;
+ 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 (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;
}
*
* "mode" (attributes) parameter may be set to -1 if it is not to be set.
*/
-static BOOL
+static bool
smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
time_t create_time,
time_t access_time,
{
int fd;
int ret;
+ TALLOC_CTX *frame = talloc_stackframe();
/*
* First, try setpathinfo (if qpathinfo succeeded), for it is the
if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) {
errno = smbc_errno(context, srv->cli);
+ TALLOC_FREE(frame);
return -1;
}
if (! ret) {
errno = smbc_errno(context, srv->cli);
+ TALLOC_FREE(frame);
return False;
}
}
+ TALLOC_FREE(frame);
return True;
}
smbc_unlink_ctx(SMBCCTX *context,
const char *fname)
{
- fstring server, share, user, password, workgroup;
- pstring path, targetpath;
- struct cli_state *targetcli;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
SMBCSRV *srv = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL; /* Best I can think of ... */
+ TALLOC_FREE(frame);
return -1;
}
if (!fname) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
- if (smbc_parse_path(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
-
+ TALLOC_FREE(frame);
return -1; /* smbc_server sets errno */
}
/*d_printf(">>>unlink: resolving %s\n", path);*/
- if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
return -1;
}
/*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/
/* Hmmm, bad error ... What? */
errno = smbc_errno(context, targetcli);
+ TALLOC_FREE(frame);
return -1;
}
}
}
+ TALLOC_FREE(frame);
return -1;
}
+ TALLOC_FREE(frame);
return 0; /* Success ... */
}
SMBCCTX *ncontext,
const char *nname)
{
- fstring server1;
- fstring share1;
- fstring server2;
- fstring share2;
- fstring user1;
- fstring user2;
- fstring password1;
- fstring password2;
- fstring workgroup;
- pstring path1;
- pstring path2;
- pstring targetpath1;
- pstring targetpath2;
- struct cli_state *targetcli1;
- struct cli_state *targetcli2;
+ char *server1 = NULL;
+ char *share1 = NULL;
+ char *server2 = NULL;
+ char *share2 = NULL;
+ char *user1 = NULL;
+ char *user2 = NULL;
+ char *password1 = NULL;
+ char *password2 = NULL;
+ char *workgroup = NULL;
+ char *path1 = NULL;
+ char *path2 = NULL;
+ char *targetpath1 = NULL;
+ char *targetpath2 = NULL;
+ struct cli_state *targetcli1 = NULL;
+ struct cli_state *targetcli2 = NULL;
SMBCSRV *srv = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
- if (!ocontext || !ncontext ||
+ if (!ocontext || !ncontext ||
!ocontext->internal || !ncontext->internal ||
- !ocontext->internal->_initialized ||
+ !ocontext->internal->_initialized ||
!ncontext->internal->_initialized) {
-
errno = EINVAL; /* Best I can think of ... */
+ TALLOC_FREE(frame);
return -1;
-
}
-
- if (!oname || !nname) {
+ if (!oname || !nname) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
-
+
DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
- smbc_parse_path(ocontext, oname,
- workgroup, sizeof(workgroup),
- server1, sizeof(server1),
- share1, sizeof(share1),
- path1, sizeof(path1),
- user1, sizeof(user1),
- password1, sizeof(password1),
- NULL, 0);
+ if (smbc_parse_path(frame,
+ ocontext,
+ oname,
+ &workgroup,
+ &server1,
+ &share1,
+ &path1,
+ &user1,
+ &password1,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
+ }
- if (user1[0] == (char)0) fstrcpy(user1, ocontext->user);
+ if (!user1 || user1[0] == (char)0) {
+ user1 = talloc_strdup(frame, ocontext->user);
+ if (!user1) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- smbc_parse_path(ncontext, nname,
- NULL, 0,
- server2, sizeof(server2),
- share2, sizeof(share2),
- path2, sizeof(path2),
- user2, sizeof(user2),
- password2, sizeof(password2),
- NULL, 0);
+ if (smbc_parse_path(frame,
+ ncontext,
+ nname,
+ NULL,
+ &server2,
+ &share2,
+ &path2,
+ &user2,
+ &password2,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
+ }
- if (user2[0] == (char)0) fstrcpy(user2, ncontext->user);
+ if (!user2 || user2[0] == (char)0) {
+ user2 = talloc_strdup(frame, ncontext->user);
+ if (!user2) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
if (strcmp(server1, server2) || strcmp(share1, share2) ||
strcmp(user1, user2)) {
-
/* Can't rename across file systems, or users?? */
-
errno = EXDEV;
+ TALLOC_FREE(frame);
return -1;
-
}
- srv = smbc_server(ocontext, True,
- server1, share1, workgroup, user1, password1);
+ srv = smbc_server(frame, ocontext, True,
+ server1, share1, &workgroup, &user1, &password1);
if (!srv) {
-
+ TALLOC_FREE(frame);
return -1;
}
/*d_printf(">>>rename: resolving %s\n", path1);*/
- if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1))
- {
+ if (!cli_resolve_path(frame, "", srv->cli, path1,
+ &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( "", srv->cli, path2, &targetcli2, targetpath2))
- {
+ if (!cli_resolve_path(frame, "", srv->cli, path2,
+ &targetcli2, &targetpath2)) {
d_printf("Could not resolve %s\n", path2);
+ TALLOC_FREE(frame);
return -1;
}
/*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/
-
+
if (strcmp(targetcli1->desthost, targetcli2->desthost) ||
strcmp(targetcli1->share, targetcli2->share))
{
/* can't rename across file systems */
-
errno = EXDEV;
+ TALLOC_FREE(frame);
return -1;
}
!cli_rename(targetcli1, targetpath1, targetpath2)) {
errno = eno;
+ TALLOC_FREE(frame);
return -1;
}
}
+ TALLOC_FREE(frame);
return 0; /* Success */
-
}
/*
int whence)
{
SMB_OFF_T size;
- fstring server, share, user, password;
- pstring path, targetpath;
- struct cli_state *targetcli;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
if (!file || !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 ... */
}
case SEEK_END:
/*d_printf(">>>lseek: parsing %s\n", file->fname);*/
- if (smbc_parse_path(context, file->fname,
- NULL, 0,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
-
- errno = EINVAL;
- return -1;
- }
-
+ if (smbc_parse_path(frame,
+ context,
+ file->fname,
+ NULL,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
/*d_printf(">>>lseek: resolving %s\n", path);*/
- if (!cli_resolve_path("", file->srv->cli, path,
- &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", file->srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ 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))
+ &size, NULL, NULL, NULL, NULL, NULL))
{
SMB_OFF_T b_size = size;
if (!cli_getattrE(targetcli, file->cli_fd,
- NULL, &b_size, NULL, NULL, NULL))
+ NULL, &b_size, NULL, NULL, NULL))
{
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
} else
size = b_size;
}
+ TALLOC_FREE(frame);
return file->offset;
}
smbc_inode(SMBCCTX *context,
const char *name)
{
-
if (!context || !context->internal ||
!context->internal->_initialized) {
SMB_OFF_T size,
int mode)
{
+ TALLOC_CTX *frame = talloc_stackframe();
st->st_mode = 0;
st->st_ino = smbc_inode(context, fname);
}
+ TALLOC_FREE(frame);
return True; /* FIXME: Is this needed ? */
}
const char *fname,
struct stat *st)
{
- SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
struct timespec write_time_ts;
struct timespec access_time_ts;
struct timespec change_time_ts;
SMB_OFF_T size = 0;
uint16 mode = 0;
SMB_INO_T ino = 0;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame,context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ 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,
+ if (!smbc_getatr(context, srv, path, &mode, &size,
NULL,
&access_time_ts,
&write_time_ts,
&change_time_ts,
&ino)) {
-
errno = smbc_errno(context, srv->cli);
+ TALLOC_FREE(frame);
return -1;
-
}
st->st_ino = ino;
set_mtimespec(st, write_time_ts);
st->st_dev = srv->dev;
+ TALLOC_FREE(frame);
return 0;
}
struct timespec write_time_ts;
SMB_OFF_T size;
uint16 mode;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- pstring path;
- pstring targetpath;
- struct cli_state *targetcli;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
SMB_INO_T ino = 0;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
-
errno = EBADF;
+ TALLOC_FREE(frame);
return -1;
-
}
if (!file->file) {
-
- return context->fstatdir(context, file, st);
-
+ TALLOC_FREE(frame);
+ return (context->fstatdir)(context, file, st);
}
/*d_printf(">>>fstat: parsing %s\n", file->fname);*/
- if (smbc_parse_path(context, file->fname,
- NULL, 0,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ file->fname,
+ NULL,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
-
+
/*d_printf(">>>fstat: resolving %s\n", path);*/
- if (!cli_resolve_path("", file->srv->cli, path,
- &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", file->srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
return -1;
}
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
&change_time, &access_time, &write_time)) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
set_mtimespec(st, write_time_ts);
st->st_dev = file->srv->dev;
+ TALLOC_FREE(frame);
return 0;
}
* Disk share = 0x00000000
* Print share = 0x00000001
* Comms share = 0x00000002 (obsolete?)
- * IPC$ share = 0x00000003
+ * IPC$ share = 0x00000003
*
* administrative shares:
* ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000
*/
-
+
if (dir->dir_type == SMBC_FILE_SHARE) {
-
switch (type) {
case 0 | 0x80000000:
case 0:
void *state)
{
int i;
- NTSTATUS result;
- uint32 enum_hnd;
+ WERROR result;
+ ENUM_HND enum_hnd;
uint32 info_level = 1;
uint32 preferred_len = 0xffffffff;
- struct srvsvc_NetShareCtr1 ctr1;
- union srvsvc_NetShareCtr ctr;
- void *mem_ctx;
+ uint32 type;
+ SRV_SHARE_INFO_CTR ctr;
+ fstring name = "";
+ fstring comment = "";
struct rpc_pipe_client *pipe_hnd;
- uint32 numentries;
NTSTATUS nt_status;
/* Open the server service pipe */
return -1;
}
- /* Allocate a context for parsing and for the entries in "ctr" */
- mem_ctx = talloc_init("libsmbclient: net_share_enum_rpc");
- if (mem_ctx == NULL) {
- DEBUG(0, ("out of memory for net_share_enum_rpc!\n"));
- cli_rpc_pipe_close(pipe_hnd);
- return -1;
- }
-
- ZERO_STRUCT(ctr1);
- ctr.ctr1 = &ctr1;
-
/* Issue the NetShareEnum RPC call and retrieve the response */
- enum_hnd = 0;
- result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL,
- &info_level, &ctr, preferred_len,
- &numentries, &enum_hnd);
+ init_enum_hnd(&enum_hnd, 0);
+ result = rpccli_srvsvc_net_share_enum(pipe_hnd,
+ talloc_tos(),
+ info_level,
+ &ctr,
+ preferred_len,
+ &enum_hnd);
/* Was it successful? */
- if (!NT_STATUS_IS_OK(result) || numentries == 0) {
+ if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) {
/* Nope. Go clean up. */
goto done;
}
/* For each returned entry... */
- for (i = 0; i < numentries; i++) {
+ for (i = 0; i < ctr.num_entries; i++) {
+
+ /* pull out the share name */
+ rpcstr_pull_unistr2_fstring(
+ name, &ctr.share.info1[i].info_1_str.uni_netname);
+
+ /* pull out the share's comment */
+ rpcstr_pull_unistr2_fstring(
+ comment, &ctr.share.info1[i].info_1_str.uni_remark);
+
+ /* Get the type value */
+ type = ctr.share.info1[i].info_1.type;
/* Add this share to the list */
- (*fn)(ctr.ctr1->array[i].name,
- ctr.ctr1->array[i].type,
- ctr.ctr1->array[i].comment, state);
+ (*fn)(name, type, comment, state);
}
done:
/* Close the server service pipe */
cli_rpc_pipe_close(pipe_hnd);
- /* Free all memory which was allocated for this request */
- TALLOC_FREE(mem_ctx);
-
/* Tell 'em if it worked */
- return NT_STATUS_IS_OK(result) ? 0 : -1;
+ return W_ERROR_IS_OK(result) ? 0 : -1;
}
const char *fname)
{
int saved_errno;
- fstring server, share, user, password, options;
- pstring workgroup;
- pstring path;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
uint16 mode;
- char *p;
+ char *p = NULL;
SMBCSRV *srv = NULL;
SMBCFILE *dir = NULL;
- struct _smbc_callbacks *cb;
- struct in_addr rem_ip;
+ struct _smbc_callbacks *cb = NULL;
+ struct sockaddr_storage rem_ss;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
DEBUG(4, ("no valid context\n"));
errno = EINVAL + 8192;
+ TALLOC_FREE(frame);
return NULL;
}
if (!fname) {
DEBUG(4, ("no valid fname\n"));
errno = EINVAL + 8193;
+ TALLOC_FREE(frame);
return NULL;
}
- if (smbc_parse_path(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- options, sizeof(options))) {
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ &options)) {
DEBUG(4, ("no valid path\n"));
errno = EINVAL + 8194;
+ TALLOC_FREE(frame);
return NULL;
}
if (smbc_check_options(server, share, path, options)) {
DEBUG(4, ("unacceptable options (%s)\n", options));
errno = EINVAL + 8195;
+ TALLOC_FREE(frame);
return NULL;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+ }
dir = SMB_MALLOC_P(SMBCFILE);
if (!dir) {
-
errno = ENOMEM;
+ TALLOC_FREE(frame);
return NULL;
-
}
ZERO_STRUCTP(dir);
struct ip_service *ip_list;
struct ip_service server_addr;
struct user_auth_info u_info;
- struct cli_state *cli;
if (share[0] != (char)0 || path[0] != (char)0) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
}
? INT_MAX
: context->options.browse_max_lmb_count);
- pstrcpy(u_info.username, user);
- pstrcpy(u_info.password, password);
+ memset(&u_info, '\0', sizeof(u_info));
+ u_info.username = talloc_strdup(frame,user);
+ u_info.password = talloc_strdup(frame,password);
+ if (!u_info.username || !u_info.password) {
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
+ TALLOC_FREE(frame);
+ return NULL;
+ }
/*
* We have server and share and path empty but options
*/
ip_list = NULL;
- if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
+ if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
+ &count)))
+ {
SAFE_FREE(ip_list);
- if (!find_master_ip(workgroup, &server_addr.ip)) {
+ if (!find_master_ip(workgroup, &server_addr.ss)) {
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
errno = ENOENT;
+ TALLOC_FREE(frame);
return NULL;
}
- ip_list = &server_addr;
+ ip_list = (struct ip_service *)memdup(
+ &server_addr, sizeof(server_addr));
+ if (ip_list == NULL) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return NULL;
+ }
count = 1;
}
for (i = 0; i < count && i < max_lmb_count; i++) {
+ char addr[INET6_ADDRSTRLEN];
+ char *wg_ptr = NULL;
+ struct cli_state *cli = NULL;
+
+ print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
DEBUG(99, ("Found master browser %d of %d: %s\n",
i+1, MAX(count, max_lmb_count),
- inet_ntoa(ip_list[i].ip)));
-
- cli = get_ipc_connect_master_ip(&ip_list[i],
- workgroup, &u_info);
- /* cli == NULL is the master browser refused to talk or
+ addr));
+
+ cli = get_ipc_connect_master_ip(talloc_tos(),
+ &ip_list[i],
+ &u_info,
+ &wg_ptr);
+ /* cli == NULL is the master browser refused to talk or
could not be found */
- if ( !cli )
+ if (!cli) {
continue;
+ }
+
+ workgroup = talloc_strdup(frame, wg_ptr);
+ server = talloc_strdup(frame, cli->desthost);
- fstrcpy(server, cli->desthost);
cli_shutdown(cli);
+ if (!workgroup || !server) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+
DEBUG(4, ("using workgroup %s %s\n",
workgroup, server));
* already have one, and determine the
* workgroups/domains that it knows about.
*/
-
- srv = smbc_server(context, True, server, "IPC$",
- workgroup, user, password);
+
+ srv = smbc_server(frame, context, True, server, "IPC$",
+ &workgroup, &user, &password);
if (!srv) {
continue;
}
-
+
dir->srv = srv;
dir->dir_type = SMBC_WORKGROUP;
/* Now, list the stuff ... */
-
+
if (!cli_NetServerEnum(srv->cli,
workgroup,
SV_TYPE_DOMAIN_ENUM,
}
SAFE_FREE(ip_list);
- } else {
+ } else {
/*
* Server not an empty string ... Check the rest and see what
* gives
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
-
+
}
/*
* establish a connection if one does not already
* exist.
*/
- srv = smbc_server(context, False, server, "IPC$",
- workgroup, user, password);
+ srv = smbc_server(frame, context, False, server, "IPC$",
+ &workgroup, &user, &password);
/*
* If no existing server and not an IP addr, look for
*/
if (!srv &&
!is_ipaddress(server) &&
- (resolve_name(server, &rem_ip, 0x1d) || /* LMB */
- resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */
+ (resolve_name(server, &rem_ss, 0x1d) || /* LMB */
+ resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */
fstring buserver;
* Get the backup list ...
*/
if (!name_status_find(server, 0, 0,
- rem_ip, buserver)) {
+ &rem_ss, buserver)) {
DEBUG(0, ("Could not get name of "
"local/domain master browser "
SAFE_FREE(dir);
}
errno = EPERM;
+ TALLOC_FREE(frame);
return NULL;
}
* Get a connection to IPC$ on the server if
* we do not already have one
*/
- srv = smbc_server(context, True,
+ 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) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
}
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
}
} else if (srv ||
- (resolve_name(server, &rem_ip, 0x20))) {
-
+ (resolve_name(server, &rem_ss, 0x20))) {
+
/* If we hadn't found the server, get one now */
if (!srv) {
- srv = smbc_server(context, True,
+ srv = smbc_server(frame, context, True,
server, "IPC$",
- workgroup,
- user, password);
+ &workgroup,
+ &user, &password);
}
if (!srv) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
}
(void *) dir) < 0 &&
cli_RNetShareEnum(
srv->cli,
- list_fn,
+ list_fn,
(void *)dir) < 0) {
-
+
errno = cli_errno(srv->cli);
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
}
} else {
/* Neither the workgroup nor server exists */
- errno = ECONNREFUSED;
+ errno = ECONNREFUSED;
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
}
* The server and share are specified ... work from
* there ...
*/
- pstring targetpath;
+ char *targetpath;
struct cli_state *targetcli;
/* We connect to the server and list the directory */
dir->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(context, True, server, share,
- workgroup, user, password);
+ srv = smbc_server(frame, context, True, server, share,
+ &workgroup, &user, &password);
if (!srv) {
-
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
-
}
dir->srv = srv;
/* Now, list the files ... */
p = path + strlen(path);
- pstrcat(path, "\\*");
+ path = talloc_asprintf_append(path, "\\*");
+ if (!path) {
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
+ TALLOC_FREE(frame);
+ return NULL;
+ }
- if (!cli_resolve_path("", srv->cli, path,
- &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
+ TALLOC_FREE(frame);
return NULL;
}
-
+
if (cli_list(targetcli, targetpath,
aDIR | aSYSTEM | aHIDDEN,
dir_list_fn, (void *)dir) < 0) {
*/
cb = &context->callbacks;
if (cli_is_error(targetcli) &&
- cb->check_server_fn(context, srv)) {
-
- /* ... then remove it. */
- if (cb->remove_unused_server_fn(context,
- srv)) {
- /*
- * We could not remove the server
- * completely, remove it from the
- * cache so we will not get it
- * again. It will be removed when the
- * last file/dir is closed.
- */
- cb->remove_cached_srv_fn(context, srv);
- }
+ (cb->check_server_fn)(context, srv)) {
+
+ /* ... then remove it. */
+ if ((cb->remove_unused_server_fn)(context,
+ srv)) {
+ /*
+ * We could not remove the
+ * server completely, remove
+ * it from the cache so we
+ * will not get it again. It
+ * will be removed when the
+ * last file/dir is closed.
+ */
+ (cb->remove_cached_srv_fn)(context,
+ srv);
+ }
}
errno = saved_errno;
+ TALLOC_FREE(frame);
return NULL;
}
}
}
DLIST_ADD(context->internal->_files, dir);
+ TALLOC_FREE(frame);
return dir;
}
smbc_closedir_ctx(SMBCCTX *context,
SMBCFILE *dir)
{
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) {
-
errno = EBADF;
+ TALLOC_FREE(frame);
return -1;
-
}
smbc_remove_dir(dir); /* Clean it up */
SAFE_FREE(dir); /* Free the space too */
}
+ TALLOC_FREE(frame);
return 0;
}
{
int maxlen;
struct smbc_dirent *dirp, *dirent;
+ TALLOC_CTX *frame = talloc_stackframe();
/* Check that all is ok first ... */
errno = EINVAL;
DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n"));
+ TALLOC_FREE(frame);
return NULL;
}
errno = EBADF;
DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n"));
+ TALLOC_FREE(frame);
return NULL;
}
errno = ENOTDIR;
DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n"));
+ TALLOC_FREE(frame);
return NULL;
}
if (!dir->dir_next) {
+ TALLOC_FREE(frame);
return NULL;
}
if (!dirent) {
errno = ENOENT;
+ TALLOC_FREE(frame);
return NULL;
}
dir->dir_next = dir->dir_next->next;
+ TALLOC_FREE(frame);
return dirp;
}
int maxlen;
char *ndir = (char *)dirp;
struct smbc_dir_list *dirlist;
+ TALLOC_CTX *frame = talloc_stackframe();
/* Check that all is ok first ... */
!context->internal->_initialized) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) {
errno = EBADF;
+ TALLOC_FREE(frame);
return -1;
}
if (dir->file != False) { /* FIXME, should be dir, perhaps */
errno = ENOTDIR;
+ TALLOC_FREE(frame);
return -1;
}
if (!dirlist->dirent) {
errno = ENOENT; /* Bad error */
+ TALLOC_FREE(frame);
return -1;
}
if (rem < count) { /* We managed to copy something */
errno = 0;
+ TALLOC_FREE(frame);
return count - rem;
}
else { /* Nothing copied ... */
errno = EINVAL; /* Not enough space ... */
+ TALLOC_FREE(frame);
return -1;
}
dir->dir_next = dirlist = dirlist -> next;
}
+ TALLOC_FREE(frame);
+
if (rem == count)
return 0;
- else
+ else
return count - rem;
}
const char *fname,
mode_t mode)
{
- SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path, targetpath;
- struct cli_state *targetcli;
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ SMBCSRV *srv = 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;
+ TALLOC_CTX *frame = talloc_stackframe();
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
if (!fname) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
-
+
DEBUG(4, ("smbc_mkdir(%s)\n", fname));
- if (smbc_parse_path(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
- return -1;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
+ TALLOC_FREE(frame);
return -1; /* errno set by smbc_server */
}
/*d_printf(">>>mkdir: resolving %s\n", path);*/
- if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
return -1;
}
/*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/
if (!cli_mkdir(targetcli, targetpath)) {
errno = smbc_errno(context, targetcli);
+ TALLOC_FREE(frame);
return -1;
}
+ TALLOC_FREE(frame);
return 0;
}
{
if (strncmp(finfo->name, ".", 1) != 0 &&
strncmp(finfo->name, "..", 2) != 0) {
-
smbc_rmdir_dirempty = False;
}
}
smbc_rmdir_ctx(SMBCCTX *context,
const char *fname)
{
- SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
- pstring targetpath;
- struct cli_state *targetcli;
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ SMBCSRV *srv = 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;
+ TALLOC_CTX *frame = talloc_stackframe();
+ if (!context || !context->internal ||
+ !context->internal->_initialized) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
if (!fname) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
-
+
DEBUG(4, ("smbc_rmdir(%s)\n", fname));
- if (smbc_parse_path(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0))
- {
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
- return -1;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
+ TALLOC_FREE(frame);
return -1; /* errno set by smbc_server */
}
/*d_printf(">>>rmdir: resolving %s\n", path);*/
- if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath))
- {
+ if (!cli_resolve_path(frame, "", srv->cli, path,
+ &targetcli, &targetpath)) {
d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
return -1;
}
/*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/
if (errno == EACCES) { /* Check if the dir empty or not */
/* Local storage to avoid buffer overflows */
- pstring lpath;
+ char *lpath;
smbc_rmdir_dirempty = True; /* Make this so ... */
- pstrcpy(lpath, targetpath);
- pstrcat(lpath, "\\*");
+ lpath = talloc_asprintf(frame, "%s\\*",
+ targetpath);
+ if (!lpath) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
if (cli_list(targetcli, lpath,
aDIR | aSYSTEM | aHIDDEN,
/* Fix errno to ignore latest error ... */
DEBUG(5, ("smbc_rmdir: "
- "cli_list returned an error: %d\n",
+ "cli_list returned an error: %d\n",
smbc_errno(context, targetcli)));
errno = EACCES;
}
+ TALLOC_FREE(frame);
return -1;
}
+ TALLOC_FREE(frame);
return 0;
}
smbc_telldir_ctx(SMBCCTX *context,
SMBCFILE *dir)
{
+ TALLOC_CTX *frame = talloc_stackframe();
+
if (!context || !context->internal ||
!context->internal->_initialized) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) {
errno = EBADF;
+ TALLOC_FREE(frame);
return -1;
}
if (dir->file != False) { /* FIXME, should be dir, perhaps */
errno = ENOTDIR;
+ TALLOC_FREE(frame);
return -1;
}
/* See if we're already at the end. */
if (dir->dir_next == NULL) {
/* We are. */
+ TALLOC_FREE(frame);
return -1;
}
/*
* We return the pointer here as the offset
*/
+ TALLOC_FREE(frame);
return (off_t)(long)dir->dir_next->dirent;
}
long int l_offset = offset; /* Handle problems of size */
struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset;
struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
if (dir->file != False) { /* FIXME, should be dir, perhaps */
errno = ENOTDIR;
+ TALLOC_FREE(frame);
return -1;
}
if (dirent == NULL) { /* Seek to the begining of the list */
dir->dir_next = dir->dir_list;
+ TALLOC_FREE(frame);
return 0;
}
+ if (offset == -1) { /* Seek to the end of the list */
+ dir->dir_next = NULL;
+ TALLOC_FREE(frame);
+ return 0;
+ }
+
/* Now, run down the list and make sure that the entry is OK */
/* This may need to be changed if we change the format of the list */
if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) {
-
errno = EINVAL; /* Bad entry */
+ TALLOC_FREE(frame);
return -1;
-
}
dir->dir_next = list_ent;
- return 0;
-
+ TALLOC_FREE(frame);
+ return 0;
}
/*
struct stat *st)
{
- if (!context || !context->internal ||
+ if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL;
return -1;
-
}
/* No code yet ... */
-
return 0;
-
}
static int
const char *fname,
mode_t newmode)
{
- SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
uint16 mode;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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_chmod(%s, 0%3o)\n", fname, newmode));
- if (smbc_parse_path(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
- return -1;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ 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_setatr(srv->cli, path, mode, 0)) {
errno = smbc_errno(context, srv->cli);
+ TALLOC_FREE(frame);
return -1;
}
-
+
+ TALLOC_FREE(frame);
return 0;
}
const char *fname,
struct timeval *tbuf)
{
- SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
time_t access_time;
time_t write_time;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!context->internal->_initialized) {
-
errno = EINVAL; /* Best I can think of ... */
+ TALLOC_FREE(frame);
return -1;
-
}
if (!fname) {
-
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
-
}
-
+
if (tbuf == NULL) {
access_time = write_time = time(NULL);
} else {
write_time = tbuf[1].tv_sec;
}
- if (DEBUGLVL(4))
- {
+ if (DEBUGLVL(4)) {
char *p;
char atimebuf[32];
char mtimebuf[32];
fname, atimebuf, mtimebuf);
}
- if (smbc_parse_path(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ 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_setatr(context, srv, path,
0, access_time, write_time, 0, 0)) {
+ TALLOC_FREE(frame);
return -1; /* errno set by smbc_setatr */
}
+ TALLOC_FREE(frame);
return 0;
}
ace_compare(SEC_ACE *ace1,
SEC_ACE *ace2)
{
- BOOL b1;
- BOOL b2;
+ bool b1;
+ bool b2;
/* If the ACEs are equal, we have nothing more to do. */
if (sec_ace_equal(ace1, ace2)) {
* referenced MS document). We'll now sort by characteristics that
* just seems reasonable.
*/
-
+
if (ace1->type != ace2->type) {
return ace2->type - ace1->type;
}
convert_sid_to_string(struct cli_state *ipc_cli,
POLICY_HND *pol,
fstring str,
- BOOL numeric,
+ bool numeric,
DOM_SID *sid)
{
char **domains = NULL;
char **names = NULL;
enum lsa_SidType *types = NULL;
struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
- sid_to_string(str, sid);
+ 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 */
- if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ipc_cli->mem_ctx,
- pol, 1, sid, &domains,
+ ctx = talloc_stackframe();
+
+ if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx,
+ pol, 1, sid, &domains,
&names, &types)) ||
!domains || !domains[0] || !names || !names[0]) {
+ TALLOC_FREE(ctx);
return;
}
+ TALLOC_FREE(ctx);
/* Converted OK */
slprintf(str, sizeof(fstring) - 1, "%s%s%s",
}
/* convert a string to a SID, either numeric or username/group */
-static BOOL
+static bool
convert_string_to_sid(struct cli_state *ipc_cli,
POLICY_HND *pol,
- BOOL numeric,
+ bool numeric,
DOM_SID *sid,
const char *str)
{
enum lsa_SidType *types = NULL;
DOM_SID *sids = NULL;
- BOOL result = True;
+ bool result = True;
+ TALLOC_CTX *ctx = NULL;
struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
if (!pipe_hnd) {
goto done;
}
- if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx,
- pol, 1, &str, NULL, 1, &sids,
- &types))) {
+ ctx = talloc_stackframe();
+ if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx,
+ pol, 1, &str, NULL, 1, &sids,
+ &types))) {
result = False;
goto done;
}
sid_copy(sid, &sids[0]);
done:
+ TALLOC_FREE(ctx);
return result;
}
/* parse an ACE in the same format as print_ace() */
-static BOOL
+static bool
parse_ace(struct cli_state *ipc_cli,
POLICY_HND *pol,
SEC_ACE *ace,
- BOOL numeric,
+ bool numeric,
char *str)
{
char *p;
const char *cp;
- fstring tok;
+ char *tok;
unsigned int atype;
unsigned int aflags;
unsigned int amask;
const char *perm;
uint32 mask;
};
+ TALLOC_CTX *frame = talloc_stackframe();
/* These values discovered by inspection */
static const struct perm_value special_values[] = {
ZERO_STRUCTP(ace);
p = strchr_m(str,':');
- if (!p) return False;
+ if (!p) {
+ TALLOC_FREE(frame);
+ return False;
+ }
*p = '\0';
p++;
/* Try to parse numeric form */
/* Try to parse text form */
if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
- return False;
+ TALLOC_FREE(frame);
+ return false;
}
cp = p;
- if (!next_token(&cp, tok, "/", sizeof(fstring))) {
- return False;
+ if (!next_token_talloc(frame, &cp, &tok, "/")) {
+ TALLOC_FREE(frame);
+ return false;
}
if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
} else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) {
atype = SEC_ACE_TYPE_ACCESS_DENIED;
} else {
- return False;
+ TALLOC_FREE(frame);
+ return false;
}
/* Only numeric form accepted for flags at present */
- if (!(next_token(&cp, tok, "/", sizeof(fstring)) &&
+ if (!(next_token_talloc(frame, &cp, &tok, "/") &&
sscanf(tok, "%i", &aflags))) {
- return False;
+ TALLOC_FREE(frame);
+ return false;
}
- if (!next_token(&cp, tok, "/", sizeof(fstring))) {
- 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) {
- return False;
+ TALLOC_FREE(frame);
+ return false;
}
goto done;
}
p = tok;
while(*p) {
- BOOL found = False;
+ bool found = False;
for (v = special_values; v->perm; v++) {
if (v->perm[0] == *p) {
}
}
- if (!found) return False;
+ if (!found) {
+ TALLOC_FREE(frame);
+ return false;
+ }
p++;
}
if (*p) {
- return False;
+ TALLOC_FREE(frame);
+ return false;
}
done:
mask = amask;
init_sec_ace(ace, &sid, atype, mask, aflags);
- return True;
+ TALLOC_FREE(frame);
+ return true;
}
/* add an ACE to a list of ACEs in a SEC_ACL */
-static BOOL
+static bool
add_ace(SEC_ACL **the_acl,
SEC_ACE *ace,
TALLOC_CTX *ctx)
sec_desc_parse(TALLOC_CTX *ctx,
struct cli_state *ipc_cli,
POLICY_HND *pol,
- BOOL numeric,
+ bool numeric,
char *str)
{
const char *p = str;
- fstring tok;
+ char *tok;
SEC_DESC *ret = NULL;
size_t sd_size;
- DOM_SID *grp_sid=NULL;
+ DOM_SID *group_sid=NULL;
DOM_SID *owner_sid=NULL;
SEC_ACL *dacl=NULL;
int revision=1;
- while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) {
+ while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) {
if (StrnCaseCmp(tok,"REVISION:", 9) == 0) {
revision = strtol(tok+9, NULL, 16);
}
if (StrnCaseCmp(tok,"GROUP:", 6) == 0) {
- if (grp_sid) {
+ if (group_sid) {
DEBUG(5, ("GROUP specified more than once!\n"));
goto done;
}
- grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
- if (!grp_sid ||
+ group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
+ if (!group_sid ||
!convert_string_to_sid(ipc_cli, pol,
numeric,
- grp_sid, tok+6)) {
+ group_sid, tok+6)) {
DEBUG(5, ("Failed to parse group sid\n"));
goto done;
}
}
if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) {
- if (grp_sid) {
+ if (group_sid) {
DEBUG(5, ("GROUP specified more than once!\n"));
goto done;
}
- grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
- if (!grp_sid ||
+ group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
+ if (!group_sid ||
!convert_string_to_sid(ipc_cli, pol,
False,
- grp_sid, tok+6)) {
+ group_sid, tok+6)) {
DEBUG(5, ("Failed to parse group sid\n"));
goto done;
}
}
ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE,
- owner_sid, grp_sid, NULL, dacl, &sd_size);
+ owner_sid, group_sid, NULL, dacl, &sd_size);
done:
- SAFE_FREE(grp_sid);
+ SAFE_FREE(group_sid);
SAFE_FREE(owner_sid);
return ret;
uint16 mode = 0;
SMB_INO_T inode = 0;
DOS_ATTR_DESC *ret;
-
+
ret = TALLOC_P(ctx, DOS_ATTR_DESC);
if (!ret) {
errno = ENOMEM;
/* Obtain the DOS attributes */
if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename),
- &mode, &size,
+ &mode, &size,
&create_time_ts,
&access_time_ts,
&write_time_ts,
- &change_time_ts,
+ &change_time_ts,
&inode)) {
-
errno = smbc_errno(context, srv->cli);
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);
{
int n;
const char *p = str;
- fstring tok;
+ char *tok = NULL;
+ TALLOC_CTX *frame = NULL;
struct {
const char * create_time_attr;
const char * access_time_attr;
}
}
- while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) {
-
+ frame = talloc_stackframe();
+ while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) {
if (StrnCaseCmp(tok, "MODE:", 5) == 0) {
dad->mode = strtol(tok+5, NULL, 16);
continue;
continue;
}
}
+ TALLOC_FREE(frame);
}
-/*****************************************************
+/*****************************************************
Retrieve the acls for a file.
*******************************************************/
uint32 i;
int n = 0;
int n_used;
- BOOL all;
- BOOL all_nt;
- BOOL all_nt_acls;
- BOOL all_dos;
- BOOL some_nt;
- BOOL some_dos;
- BOOL exclude_nt_revision = False;
- BOOL exclude_nt_owner = False;
- BOOL exclude_nt_group = False;
- BOOL exclude_nt_acl = False;
- BOOL exclude_dos_mode = False;
- BOOL exclude_dos_size = False;
- BOOL exclude_dos_create_time = False;
- BOOL exclude_dos_access_time = False;
- BOOL exclude_dos_write_time = False;
- BOOL exclude_dos_change_time = False;
- BOOL exclude_dos_inode = False;
- BOOL numeric = True;
- BOOL determine_size = (bufsize == 0);
+ bool all;
+ bool all_nt;
+ bool all_nt_acls;
+ bool all_dos;
+ bool some_nt;
+ bool some_dos;
+ bool exclude_nt_revision = False;
+ bool exclude_nt_owner = False;
+ bool exclude_nt_group = False;
+ bool exclude_nt_acl = False;
+ bool exclude_dos_mode = False;
+ bool exclude_dos_size = False;
+ bool exclude_dos_create_time = False;
+ bool exclude_dos_access_time = False;
+ bool exclude_dos_write_time = False;
+ bool exclude_dos_change_time = False;
+ bool exclude_dos_inode = False;
+ bool numeric = True;
+ bool determine_size = (bufsize == 0);
int fnum = -1;
SEC_DESC *sd;
fstring sidstr;
sd->revision);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
&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);
"0x%x", mode);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
(double)size);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
"%lu", create_time);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
"%lu", access_time);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
"%lu", write_time);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
"%lu", change_time);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
(double) ino);
}
}
-
+
if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
return n_used;
}
-
-/*****************************************************
+/*****************************************************
set the ACLs on a file given an ascii description
*******************************************************/
static int
int err = 0;
SEC_DESC *sd = NULL, *old;
SEC_ACL *dacl = NULL;
- DOM_SID *owner_sid = NULL;
- DOM_SID *grp_sid = NULL;
+ DOM_SID *owner_sid = NULL;
+ DOM_SID *group_sid = NULL;
uint32 i, j;
size_t sd_size;
int ret = 0;
char *p;
- BOOL numeric = True;
+ bool numeric = True;
/* the_acl will be null for REMOVE_ALL operations */
if (the_acl) {
case SMBC_XATTR_MODE_REMOVE:
for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
- BOOL found = False;
+ bool found = False;
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
if (sec_ace_equal(&sd->dacl->aces[i],
case SMBC_XATTR_MODE_ADD:
for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
- BOOL found = False;
+ bool found = False;
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
if (sid_equal(&sd->dacl->aces[i].trustee,
ret = -1;
goto failed;
}
-
+
for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
add_ace(&old->dacl, &sd->dacl->aces[i], ctx);
}
case SMBC_XATTR_MODE_SET:
old = sd;
owner_sid = old->owner_sid;
- grp_sid = old->group_sid;
+ group_sid = old->group_sid;
dacl = old->dacl;
break;
break;
case SMBC_XATTR_MODE_CHGRP:
- grp_sid = sd->group_sid;
+ group_sid = sd->group_sid;
break;
}
sort_acl(old->dacl);
/* Create new security descriptor and set it */
- sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE,
- owner_sid, grp_sid, NULL, dacl, &sd_size);
+ sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE,
+ owner_sid, group_sid, NULL, dacl, &sd_size);
fnum = cli_nt_create(cli, filename,
WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS);
if (err != 0) {
errno = err;
}
-
+
return ret;
}
{
int ret;
int ret2;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
- TALLOC_CTX *ctx;
+ SMBCSRV *srv = NULL;
+ SMBCSRV *ipc_srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
POLICY_HND pol;
- DOS_ATTR_DESC *dad;
+ DOS_ATTR_DESC *dad = NULL;
struct {
const char * create_time_attr;
const char * access_time_attr;
const char * write_time_attr;
const char * change_time_attr;
} attr_strings;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ 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(context, server, share,
- workgroup, user, password,
+ ipc_srv = smbc_attr_server(frame, context, server, share,
+ &workgroup, &user, &password,
&pol);
if (! ipc_srv) {
srv->no_nt_session = True;
} else {
ipc_srv = NULL;
}
-
- ctx = talloc_init("smbc_setxattr");
- if (!ctx) {
- errno = ENOMEM;
- return -1;
- }
/*
* Are they asking to set the entire set of known attributes?
StrCaseCmp(name, "system.*+") == 0) {
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
+ talloc_asprintf(talloc_tos(), "%s:%s",
name+7, (const char *) value);
if (! namevalue) {
errno = ENOMEM;
ret = -1;
+ TALLOC_FREE(frame);
return -1;
}
if (ipc_srv) {
- ret = cacl_set(ctx, srv->cli,
+ ret = cacl_set(talloc_tos(), srv->cli,
ipc_srv->cli, &pol, path,
namevalue,
(*namevalue == '*'
}
/* get a DOS Attribute Descriptor with current attributes */
- dad = dos_attr_query(context, ctx, path, srv);
+ 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);
ret = 0;
}
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
+ talloc_asprintf(talloc_tos(), "%s:%s",
name+19, (const char *) value);
if (! ipc_srv) {
errno = ENOMEM;
ret = -1;
} else {
- ret = cacl_set(ctx, srv->cli,
+ ret = cacl_set(talloc_tos(), srv->cli,
ipc_srv->cli, &pol, path,
namevalue,
(*namevalue == '*'
: SMBC_XATTR_MODE_ADD),
flags);
}
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
+ talloc_asprintf(talloc_tos(), "%s:%s",
name+19, (const char *) value);
if (! ipc_srv) {
-
ret = -1; /* errno set by smbc_server() */
}
else if (! namevalue) {
errno = ENOMEM;
ret = -1;
} else {
- ret = cacl_set(ctx, srv->cli,
+ ret = cacl_set(talloc_tos(), srv->cli,
ipc_srv->cli, &pol, path,
namevalue, SMBC_XATTR_MODE_CHOWN, 0);
}
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
+ talloc_asprintf(talloc_tos(), "%s:%s",
name+19, (const char *) value);
if (! ipc_srv) {
errno = ENOMEM;
ret = -1;
} else {
- ret = cacl_set(ctx, srv->cli,
+ ret = cacl_set(talloc_tos(), srv->cli,
ipc_srv->cli, &pol, path,
namevalue, SMBC_XATTR_MODE_CHOWN, 0);
}
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
StrCaseCmp(name, attr_strings.change_time_attr) == 0) {
/* get a DOS Attribute Descriptor with current attributes */
- dad = dos_attr_query(context, ctx, path, srv);
+ dad = dos_attr_query(context, talloc_tos(), path, srv);
if (dad) {
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
+ talloc_asprintf(talloc_tos(), "%s:%s",
name+16, (const char *) value);
if (! namevalue) {
errno = ENOMEM;
ret = -1;
}
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
/* Unsupported attribute name */
- talloc_destroy(ctx);
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
size_t size)
{
int ret;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
- TALLOC_CTX *ctx;
+ SMBCSRV *srv = NULL;
+ SMBCSRV *ipc_srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
POLICY_HND pol;
struct {
const char * create_time_attr;
const char * write_time_attr;
const char * change_time_attr;
} attr_strings;
-
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ 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(context, server, share,
- workgroup, user, password,
+ ipc_srv = smbc_attr_server(frame, context, server, share,
+ &workgroup, &user, &password,
&pol);
if (! ipc_srv) {
srv->no_nt_session = True;
} else {
ipc_srv = NULL;
}
-
- ctx = talloc_init("smbc:getxattr");
- if (!ctx) {
- errno = ENOMEM;
- return -1;
- }
/* Determine whether to use old-style or new-style attribute names */
if (context->internal->_full_time_names) {
StrCaseCmp(name, "system.dos_attr.inode") == 0) {
/* Yup. */
- ret = cacl_get(context, ctx, srv,
+ ret = cacl_get(context, talloc_tos(), srv,
ipc_srv == NULL ? NULL : ipc_srv->cli,
&pol, path,
CONST_DISCARD(char *, name),
if (ret < 0 && errno == 0) {
errno = smbc_errno(context, srv->cli);
}
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
/* Unsupported attribute name */
- talloc_destroy(ctx);
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
const char *name)
{
int ret;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
- TALLOC_CTX *ctx;
+ SMBCSRV *srv = NULL;
+ SMBCSRV *ipc_srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
POLICY_HND pol;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ 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(context, server, share,
- workgroup, user, password,
+ ipc_srv = smbc_attr_server(frame, context, server, share,
+ &workgroup, &user, &password,
&pol);
if (! ipc_srv) {
srv->no_nt_session = True;
} else {
ipc_srv = NULL;
}
-
+
if (! ipc_srv) {
+ TALLOC_FREE(frame);
return -1; /* errno set by smbc_attr_server */
}
- ctx = talloc_init("smbc_removexattr");
- if (!ctx) {
- errno = ENOMEM;
- return -1;
- }
-
/* 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(ctx, srv->cli,
+ ret = cacl_set(talloc_tos(), srv->cli,
ipc_srv->cli, &pol, path,
NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0);
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
/* Yup. */
- ret = cacl_set(ctx, srv->cli,
+ ret = cacl_set(talloc_tos(), srv->cli,
ipc_srv->cli, &pol, path,
name + 19, SMBC_XATTR_MODE_REMOVE, 0);
- talloc_destroy(ctx);
+ TALLOC_FREE(frame);
return ret;
}
/* Unsupported attribute name */
- talloc_destroy(ctx);
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
* the complete set of attribute names, always, rather than only those
* attribute names which actually exist for a file. Hmmm...
*/
+ size_t retsize;
const char supported_old[] =
"system.*\0"
"system.*+\0"
if (context->internal->_full_time_names) {
supported = supported_new;
+ retsize = sizeof(supported_new);
} else {
supported = supported_old;
+ retsize = sizeof(supported_old);
}
if (size == 0) {
- return sizeof(supported);
+ return retsize;
}
- if (sizeof(supported) > size) {
+ if (retsize > size) {
errno = ERANGE;
return -1;
}
/* this can't be strcpy() because there are embedded null characters */
- memcpy(list, supported, sizeof(supported));
- return sizeof(supported);
+ memcpy(list, supported, retsize);
+ return retsize;
}
smbc_open_print_job_ctx(SMBCCTX *context,
const char *fname)
{
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- pstring path;
-
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *path = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+
if (!context || !context->internal ||
!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(context, fname,
- NULL, 0,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ NULL,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
errno = EINVAL;
+ TALLOC_FREE(frame);
return NULL;
}
/* What if the path is empty, or the file exists? */
- return context->open(context, fname, O_WRONLY, 666);
-
+ TALLOC_FREE(frame);
+ return (context->open)(context, fname, O_WRONLY, 666);
}
/*
int saverr;
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 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
-
+ if ((long)(fid1 = (c_file->open)(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 = c_print->open_print_job(c_print, printq)) < 0) {
+ if ((long)(fid2 = (c_print->open_print_job)(c_print, printq)) < 0) {
saverr = errno; /* Save errno */
- c_file->close_fn(c_file, fid1);
+ (c_file->close_fn)(c_file, fid1);
errno = saverr;
+ TALLOC_FREE(frame);
return -1;
}
- while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) {
+ while ((bytes = (c_file->read)(c_file, fid1, buf, sizeof(buf))) > 0) {
tot_bytes += bytes;
- if ((c_print->write(c_print, fid2, buf, bytes)) < 0) {
+ if (((c_print->write)(c_print, fid2, buf, bytes)) < 0) {
saverr = errno;
- c_file->close_fn(c_file, fid1);
- c_print->close_fn(c_print, fid2);
+ (c_file->close_fn)(c_file, fid1);
+ (c_print->close_fn)(c_print, fid2);
errno = saverr;
}
saverr = errno;
- c_file->close_fn(c_file, fid1); /* We have to close these anyway */
- c_print->close_fn(c_print, fid2);
+ (c_file->close_fn)(c_file, fid1); /* We have to close these anyway */
+ (c_print->close_fn)(c_print, fid2);
if (bytes < 0) {
errno = saverr;
+ TALLOC_FREE(frame);
return -1;
}
+ TALLOC_FREE(frame);
return tot_bytes;
}
const char *fname,
smbc_list_print_job_fn fn)
{
- SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- if (!srv) {
+ 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;
}
const char *fname,
int id)
{
- SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
int err;
+ TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
!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(context, fname,
- workgroup, sizeof(workgroup),
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
+ if (smbc_parse_path(frame,
+ context,
+ fname,
+ &workgroup,
+ &server,
+ &share,
+ &path,
+ &user,
+ &password,
+ NULL)) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
}
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (!user || user[0] == (char)0) {
+ user = talloc_strdup(frame, context->user);
+ if (!user) {
+ errno = ENOMEM;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ }
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
+ TALLOC_FREE(frame);
return -1; /* errno set by smbc_server */
}
errno = smbc_errno(context, srv->cli);
else if (err == ERRnosuchprintjob)
errno = EINVAL;
+ TALLOC_FREE(frame);
return -1;
}
+ TALLOC_FREE(frame);
return 0;
}
/*
- * Get a new empty handle to fill in with your own info
+ * Get a new empty handle to fill in with your own info
*/
SMBCCTX *
smbc_new_context(void)
ZERO_STRUCTP(context->internal);
-
/* ADD REASONABLE DEFAULTS */
context->debug = 0;
context->timeout = 20000; /* 20 seconds */
return context;
}
-/*
+/*
* Free a context
*
- * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
+ * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
* and thus you'll be leaking memory if not handled properly.
*
*/
errno = EBADF;
return 1;
}
-
+
if (shutdown_ctx) {
SMBCFILE * f;
DEBUG(1,("Performing aggressive shutdown.\n"));
-
+
f = context->internal->_files;
while (f) {
- context->close_fn(context, f);
+ (context->close_fn)(context, f);
f = f->next;
}
context->internal->_files = NULL;
DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
s, s->cli->fd));
cli_shutdown(s->cli);
- context->callbacks.remove_cached_srv_fn(context,
- s);
+ (context->callbacks.remove_cached_srv_fn)(context,
+ s);
next = s->next;
DLIST_REMOVE(context->internal->_servers, s);
SAFE_FREE(s);
}
}
else {
- /* This is the polite way */
- if (context->callbacks.purge_cached_fn(context)) {
+ /* This is the polite way */
+ if ((context->callbacks.purge_cached_fn)(context)) {
DEBUG(1, ("Could not purge all servers, "
"free_context failed.\n"));
errno = EBUSY;
"free_context failed.\n"));
errno = EBUSY;
return 1;
- }
+ }
}
/* Things we have to clean up */
SAFE_FREE(context->workgroup);
SAFE_FREE(context->netbios_name);
SAFE_FREE(context->user);
-
+
DEBUG(3, ("Context %p succesfully freed\n", context));
SAFE_FREE(context->internal);
SAFE_FREE(context);
va_list ap;
union {
int i;
- BOOL b;
+ bool b;
smbc_get_auth_data_with_context_fn auth_fn;
void *v;
+ const char *s;
} option_value;
va_start(ap, option_name);
/*
* Log to standard error instead of standard output.
*/
- option_value.b = (BOOL) va_arg(ap, int);
+ option_value.b = (bool) va_arg(ap, int);
context->internal->_debug_stderr = option_value.b;
} else if (strcmp(option_name, "full_time_names") == 0) {
* be CHANGE_TIME but was confused and sometimes referred to
* CREATE_TIME.)
*/
- option_value.b = (BOOL) va_arg(ap, int);
+ option_value.b = (bool) va_arg(ap, int);
context->internal->_full_time_names = option_value.b;
} else if (strcmp(option_name, "open_share_mode") == 0) {
*/
option_value.v = va_arg(ap, void *);
context->internal->_user_data = option_value.v;
+ } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
+ /*
+ * Save an encoded value for encryption level.
+ * 0 = off, 1 = attempt, 2 = required.
+ */
+ option_value.s = va_arg(ap, const char *);
+ if (strcmp(option_value.s, "none") == 0) {
+ context->internal->_smb_encryption_level = 0;
+ } else if (strcmp(option_value.s, "request") == 0) {
+ context->internal->_smb_encryption_level = 1;
+ } else if (strcmp(option_value.s, "require") == 0) {
+ context->internal->_smb_encryption_level = 2;
+ }
}
va_end(ap);
* with smbc_option_get()
*/
return context->internal->_user_data;
+ } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
+ /*
+ * Return the current smb encrypt negotiate option as a string.
+ */
+ switch (context->internal->_smb_encryption_level) {
+ case 0:
+ return (void *) "none";
+ case 1:
+ return (void *) "request";
+ case 2:
+ return (void *) "require";
+ }
+ } else if (strcmp(option_name, "smb_encrypt_on") == 0) {
+ /*
+ * Return the current smb encrypt status option as a bool.
+ * false = off, true = on. We don't know what server is
+ * being requested, so we only return true if all servers
+ * are using an encrypted connection.
+ */
+ SMBCSRV *s;
+ unsigned int num_servers = 0;
+
+ for (s = context->internal->_servers; s; s = s->next) {
+ num_servers++;
+ if (s->cli->trans_enc_state == NULL) {
+ return (void *)false;
+ }
+ }
+ return (void *) (bool) (num_servers > 0);
}
return NULL;
/*
- * Initialise the library etc
+ * Initialise the library etc
*
* We accept a struct containing handle information.
* valid values for info->debug from 0 to 100,
SMBCCTX *
smbc_init_context(SMBCCTX *context)
{
- pstring conf;
int pid;
char *user = NULL;
char *home = NULL;
}
/* Do not initialise the same client twice */
- if (context->internal->_initialized) {
+ if (context->internal->_initialized) {
return 0;
}
* Do some library-wide intializations the first time we get
* called
*/
- BOOL conf_loaded = False;
+ bool conf_loaded = False;
+ TALLOC_CTX *frame = talloc_stackframe();
/* Set this to what the user wants */
DEBUGLEVEL = context->debug;
-
+
load_case_tables();
setup_logging("libsmbclient", True);
}
/* Here we would open the smb.conf file if needed ... */
-
+
in_client = True; /* FIXME, make a param */
home = getenv("HOME");
if (home) {
- slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
- if (lp_load(conf, True, False, False, True)) {
- conf_loaded = True;
- } else {
- DEBUG(5, ("Could not load config file: %s\n",
- conf));
+ char *conf = NULL;
+ if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
+ if (lp_load(conf, True, False, False, True)) {
+ conf_loaded = True;
+ } else {
+ DEBUG(5, ("Could not load config file: %s\n",
+ conf));
+ }
+ SAFE_FREE(conf);
}
}
-
+
if (!conf_loaded) {
/*
- * Well, if that failed, try the dyn_CONFIGFILE
+ * Well, if that failed, try the get_dyn_CONFIGFILE
* Which points to the standard locn, and if that
* fails, silently ignore it and use the internal
* defaults ...
*/
- if (!lp_load(dyn_CONFIGFILE, True, False, False, False)) {
+ if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) {
DEBUG(5, ("Could not load config file: %s\n",
- dyn_CONFIGFILE));
+ get_dyn_CONFIGFILE()));
} else if (home) {
+ char *conf;
/*
* We loaded the global config file. Now lets
* load user-specific modifications to the
* global config.
*/
- slprintf(conf, sizeof(conf),
- "%s/.smb/smb.conf.append", home);
- if (!lp_load(conf, True, False, False, False)) {
- DEBUG(10,
- ("Could not append config file: "
- "%s\n",
- conf));
- }
+ if (asprintf(&conf,
+ "%s/.smb/smb.conf.append",
+ home) > 0) {
+ if (!lp_load(conf, True, False, False, False)) {
+ DEBUG(10,
+ ("Could not append config file: "
+ "%s\n",
+ conf));
+ }
+ SAFE_FREE(conf);
+ }
}
}
load_interfaces(); /* Load the list of interfaces ... */
-
+
reopen_logs(); /* Get logging working ... */
-
- /*
- * Block SIGPIPE (from lib/util_sock.c: write())
- * It is not needed and should not stop execution
+
+ /*
+ * Block SIGPIPE (from lib/util_sock.c: write())
+ * It is not needed and should not stop execution
*/
BlockSignals(True, SIGPIPE);
-
+
/* Done with one-time initialisation */
- smbc_initialized = 1;
+ smbc_initialized = 1;
+ TALLOC_FREE(frame);
}
-
+
if (!context->user) {
/*
- * FIXME: Is this the best way to get the user info?
+ * FIXME: Is this the best way to get the user info?
*/
user = getenv("USER");
/* walk around as "guest" if no username can be found */
}
DEBUG(1, ("Using workgroup %s.\n", context->workgroup));
-
+
/* shortest timeout is 1 second */
- if (context->timeout > 0 && context->timeout < 1000)
+ if (context->timeout > 0 && context->timeout < 1000)
context->timeout = 1000;
/*
- * FIXME: Should we check the function pointers here?
+ * FIXME: Should we check the function pointers here?
*/
context->internal->_initialized = True;
-
+
return context;
}