summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/cliconnect.c25
-rw-r--r--source3/libsmb/libsmb_context.c44
-rw-r--r--source3/libsmb/libsmb_dir.c29
-rw-r--r--source3/libsmb/libsmb_file.c2
-rw-r--r--source3/libsmb/libsmb_path.c21
-rw-r--r--source3/libsmb/libsmb_server.c19
-rw-r--r--source3/libsmb/libsmb_stat.c2
-rw-r--r--source3/libsmb/nmblib.c15
-rw-r--r--source3/libsmb/ntlmssp.c12
-rw-r--r--source3/libsmb/smb_share_modes.c39
10 files changed, 167 insertions, 41 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index dabfc398ce..ad11ee0ed4 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1642,6 +1642,7 @@ bool cli_session_request(struct cli_state *cli,
{
char *p;
int len = 4;
+ char *tmp;
/* 445 doesn't have session request */
if (cli->port == 445)
@@ -1651,14 +1652,30 @@ bool cli_session_request(struct cli_state *cli,
memcpy(&(cli->called ), called , sizeof(*called ));
/* put in the destination name */
+
+ tmp = name_mangle(talloc_tos(), cli->called.name,
+ cli->called.name_type);
+ if (tmp == NULL) {
+ return false;
+ }
+
p = cli->outbuf+len;
- name_mangle(cli->called .name, p, cli->called .name_type);
- len += name_len(p);
+ memcpy(p, tmp, name_len(tmp));
+ len += name_len(tmp);
+ TALLOC_FREE(tmp);
/* and my name */
+
+ tmp = name_mangle(talloc_tos(), cli->calling.name,
+ cli->calling.name_type);
+ if (tmp == NULL) {
+ return false;
+ }
+
p = cli->outbuf+len;
- name_mangle(cli->calling.name, p, cli->calling.name_type);
- len += name_len(p);
+ memcpy(p, tmp, name_len(tmp));
+ len += name_len(tmp);
+ TALLOC_FREE(tmp);
/* send a session request (RFC 1002) */
/* setup the packet length
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index c1af48507c..4c12d18ab7 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -630,11 +630,11 @@ smbc_version(void)
* Set the credentials so DFS will work when following referrals.
*/
void
-smbc_set_credentials(char *workgroup,
- char *user,
- char *password,
+smbc_set_credentials(const char *workgroup,
+ const char *user,
+ const char *password,
smbc_bool use_kerberos,
- char *signing_state)
+ const char *signing_state)
{
struct user_auth_info *auth_info;
@@ -652,3 +652,39 @@ smbc_set_credentials(char *workgroup,
cli_cm_set_credentials(auth_info);
TALLOC_FREE(auth_info);
}
+
+void smbc_set_credentials_with_fallback(SMBCCTX *context,
+ const char *workgroup,
+ const char *user,
+ const char *password)
+{
+ smbc_bool use_kerberos = false;
+ const char *signing_state = "off";
+
+ if (! context ||
+ ! workgroup || ! *workgroup ||
+ ! user || ! *user ||
+ ! password || ! *password) {
+
+ return;
+ }
+
+ if (smbc_getOptionUseKerberos(context)) {
+ use_kerberos = True;
+ }
+
+ if (lp_client_signing()) {
+ signing_state = "on";
+ }
+
+ if (lp_client_signing() == Required) {
+ signing_state = "force";
+ }
+
+ smbc_set_credentials(workgroup, user, password,
+ use_kerberos, signing_state);
+
+ if (smbc_getOptionFallbackAfterKerberos(context)) {
+ cli_cm_set_fallback_after_kerberos();
+ }
+}
diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c
index e9b7b4f95a..56661af70b 100644
--- a/source3/libsmb/libsmb_dir.c
+++ b/source3/libsmb/libsmb_dir.c
@@ -1500,6 +1500,8 @@ SMBC_chmod_ctx(SMBCCTX *context,
char *user = NULL;
char *password = NULL;
char *workgroup = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
char *path = NULL;
uint16 mode;
TALLOC_CTX *frame = talloc_stackframe();
@@ -1517,7 +1519,7 @@ SMBC_chmod_ctx(SMBCCTX *context,
return -1;
}
- DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
+ DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, (unsigned int)newmode));
if (SMBC_parse_path(frame,
context,
@@ -1550,6 +1552,14 @@ SMBC_chmod_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1; /* errno set by SMBC_server */
}
+
+ /*d_printf(">>>unlink: resolving %s\n", path);*/
+ if (!cli_resolve_path(frame, "", srv->cli, path,
+ &targetcli, &targetpath)) {
+ d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
+ return -1;
+ }
mode = 0;
@@ -1558,8 +1568,8 @@ SMBC_chmod_ctx(SMBCCTX *context,
if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
- if (!cli_setatr(srv->cli, path, mode, 0)) {
- errno = SMBC_errno(context, srv->cli);
+ if (!cli_setatr(targetcli, targetpath, mode, 0)) {
+ errno = SMBC_errno(context, targetcli);
TALLOC_FREE(frame);
return -1;
}
@@ -1900,6 +1910,12 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
}
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(ocontext,
+ workgroup,
+ user1,
+ password1);
+
/*d_printf(">>>rename: resolving %s\n", path1);*/
if (!cli_resolve_path(frame, "", srv->cli, path1,
&targetcli1, &targetpath1)) {
@@ -1907,6 +1923,13 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
TALLOC_FREE(frame);
return -1;
}
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(ncontext,
+ workgroup,
+ user2,
+ password2);
+
/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
/*d_printf(">>>rename: resolving %s\n", path2);*/
if (!cli_resolve_path(frame, "", srv->cli, path2,
diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c
index ece056db87..28256bb241 100644
--- a/source3/libsmb/libsmb_file.c
+++ b/source3/libsmb/libsmb_file.c
@@ -382,7 +382,7 @@ SMBC_write_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1;
}
-
+
/*d_printf(">>>write: resolving %s\n", path);*/
if (!cli_resolve_path(frame, "", file->srv->cli, path,
&targetcli, &targetpath)) {
diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c
index 6d69924231..6a59a12ed0 100644
--- a/source3/libsmb/libsmb_path.c
+++ b/source3/libsmb/libsmb_path.c
@@ -216,7 +216,7 @@ smbc_urlencode(char *dest,
* are supported.
*/
-static const char *smbc_prefix = "smb:";
+#define SMBC_PREFIX "smb:"
int
SMBC_parse_path(TALLOC_CTX *ctx,
@@ -233,6 +233,7 @@ SMBC_parse_path(TALLOC_CTX *ctx,
char *s;
const char *p;
char *q, *r;
+ char *workgroup = NULL;
int len;
/* Ensure these returns are at least valid pointers. */
@@ -262,8 +263,8 @@ SMBC_parse_path(TALLOC_CTX *ctx,
s = talloc_strdup(ctx, fname);
/* see if it has the right prefix */
- len = strlen(smbc_prefix);
- if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) {
+ len = strlen(SMBC_PREFIX);
+ if (strncmp(s,SMBC_PREFIX,len) || (s[len] != '/' && s[len] != 0)) {
return -1; /* What about no smb: ? */
}
@@ -332,7 +333,6 @@ SMBC_parse_path(TALLOC_CTX *ctx,
u = userinfo;
if (strchr_m(u, ';')) {
- char *workgroup;
next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
if (!workgroup) {
return -1;
@@ -394,6 +394,19 @@ decoding:
(void) urldecode_talloc(ctx, pp_share, *pp_share);
(void) urldecode_talloc(ctx, pp_user, *pp_user);
(void) urldecode_talloc(ctx, pp_password, *pp_password);
+
+ if (!workgroup) {
+ workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
+ }
+ if (!workgroup) {
+ return -1;
+ }
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(context,
+ workgroup,
+ *pp_user,
+ *pp_password);
return 0;
}
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 6d7a86241a..eda37f2187 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -238,6 +238,7 @@ SMBC_server(TALLOC_CTX *ctx,
char **pp_password)
{
SMBCSRV *srv=NULL;
+ char *workgroup = NULL;
struct cli_state *c;
struct nmb_name called, calling;
const char *server_n = server;
@@ -359,7 +360,7 @@ SMBC_server(TALLOC_CTX *ctx,
if (srv) {
/* ... then we're done here. Give 'em what they came for. */
- return srv;
+ goto done;
}
/* If we're not asked to connect when a connection doesn't exist... */
@@ -601,6 +602,22 @@ again:
server, share, srv));
DLIST_ADD(context->internal->servers, srv);
+done:
+ if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
+ workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
+ } else {
+ workgroup = *pp_workgroup;
+ }
+ if(!workgroup) {
+ return NULL;
+ }
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(context,
+ workgroup,
+ *pp_username,
+ *pp_password);
+
return srv;
failed:
diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c
index 1ffe141796..f8571ff110 100644
--- a/source3/libsmb/libsmb_stat.c
+++ b/source3/libsmb/libsmb_stat.c
@@ -155,7 +155,7 @@ SMBC_stat_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1;
}
-
+
if (!user || user[0] == (char)0) {
user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 02b13ae63e..5f3eda44fe 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -1279,12 +1279,19 @@ static int name_interpret(char *in, fstring name)
Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
****************************************************************************/
-int name_mangle( char *In, char *Out, char name_type )
+char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type)
{
int i;
int len;
nstring buf;
- char *p = Out;
+ char *result;
+ char *p;
+
+ result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2);
+ if (result == NULL) {
+ return NULL;
+ }
+ p = result;
/* Safely copy the input string, In, into buf[]. */
if (strcmp(In,"*") == 0)
@@ -1321,7 +1328,7 @@ int name_mangle( char *In, char *Out, char name_type )
p[0] = len;
if( len > 0 )
p[len+1] = 0;
- return( name_len(Out) );
+ return result;
case '.':
p[0] = len;
p += (len + 1);
@@ -1333,7 +1340,7 @@ int name_mangle( char *In, char *Out, char name_type )
}
}
- return( name_len(Out) );
+ return result;
}
/****************************************************************************
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
index cc13476935..0764f97d85 100644
--- a/source3/libsmb/ntlmssp.c
+++ b/source3/libsmb/ntlmssp.c
@@ -110,12 +110,10 @@ void debug_ntlmssp_flags(uint32 neg_flags)
*
*/
-static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
+static void get_challenge(const struct ntlmssp_state *ntlmssp_state,
+ uint8_t chal[8])
{
- static uchar chal[8];
- generate_random_buffer(chal, sizeof(chal));
-
- return chal;
+ generate_random_buffer(chal, 8);
}
/**
@@ -517,7 +515,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
char *dnsdomname = NULL;
uint32 neg_flags = 0;
uint32 ntlmssp_command, chal_flags;
- const uint8 *cryptkey;
+ uint8_t cryptkey[8];
const char *target_name;
/* parse the NTLMSSP packet */
@@ -541,7 +539,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
/* Ask our caller what challenge they would like in the packet */
- cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
+ ntlmssp_state->get_challenge(ntlmssp_state, cryptkey);
/* Check if we may set the challenge */
if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c
index af3f7b0dd5..177e0114b3 100644
--- a/source3/libsmb/smb_share_modes.c
+++ b/source3/libsmb/smb_share_modes.c
@@ -38,7 +38,8 @@ struct smbdb_ctx {
#endif
int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev,
- uint64_t ino, const struct smb_share_mode_entry *new_entry,
+ uint64_t ino, uint64_t extid,
+ const struct smb_share_mode_entry *new_entry,
const char *sharepath, const char *filename);
static bool sharemodes_procid_equal(const struct server_id *p1, const struct server_id *p2)
@@ -83,6 +84,7 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path)
struct locking_key {
SMB_DEV_T dev;
SMB_INO_T inode;
+ uint64_t extid;
};
int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
@@ -93,13 +95,14 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
}
static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
- uint64_t ino)
+ uint64_t ino, uint64_t extid)
{
TDB_DATA ld;
memset(lk, '\0', sizeof(*lk));
lk->dev = (SMB_DEV_T)dev;
lk->inode = (SMB_INO_T)ino;
+ lk->extid = extid;
ld.dptr = (uint8 *)lk;
ld.dsize = sizeof(*lk);
return ld;
@@ -111,19 +114,22 @@ static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
- uint64_t ino)
+ uint64_t ino,
+ uint64_t extid)
{
struct locking_key lk;
- return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
+ return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino,
+ extid));
}
int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
- uint64_t ino)
+ uint64_t ino,
+ uint64_t extid)
{
struct locking_key lk;
return tdb_chainunlock(db_ctx->smb_tdb,
- get_locking_key(&lk, dev, ino));
+ get_locking_key(&lk, dev, ino, extid));
}
/*
@@ -140,7 +146,8 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry,
e_entry->share_access == (uint32_t)entry->share_access &&
e_entry->access_mask == (uint32_t)entry->access_mask &&
e_entry->dev == entry->id.devid &&
- e_entry->ino == entry->id.inode);
+ e_entry->ino == entry->id.inode &&
+ e_entry->extid == entry->id.extid);
}
/*
@@ -160,6 +167,7 @@ static void create_share_mode_entry(struct share_mode_entry *out,
out->access_mask = in->access_mask;
out->id.devid = in->dev;
out->id.inode = in->ino;
+ out->id.extid = in->extid;
out->uid = (uint32)geteuid();
out->flags = 0;
}
@@ -172,6 +180,7 @@ static void create_share_mode_entry(struct share_mode_entry *out,
int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
struct smb_share_mode_entry **pp_list,
unsigned char *p_delete_on_close)
{
@@ -187,7 +196,8 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
*pp_list = NULL;
*p_delete_on_close = 0;
- db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
+ db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino,
+ extid));
if (!db_data.dptr) {
return 0;
}
@@ -229,6 +239,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
/* Copy into the external list. */
sme->dev = share->id.devid;
sme->ino = share->id.inode;
+ sme->extid = share->id.extid;
sme->share_access = (uint32_t)share->share_access;
sme->access_mask = (uint32_t)share->access_mask;
sme->open_time.tv_sec = share->time.tv_sec;
@@ -257,13 +268,14 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *new_entry,
const char *sharepath, /* Must be absolute utf8 path. */
const char *filename) /* Must be relative utf8 path. */
{
TDB_DATA db_data;
struct locking_key lk;
- TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -360,24 +372,26 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *new_entry,
const char *filename) /* Must be absolute utf8 path. */
{
if (*filename != '/') {
abort();
}
- return smb_create_share_mode_entry_ex(db_ctx, dev, ino, new_entry,
+ return smb_create_share_mode_entry_ex(db_ctx, dev, ino, extid, new_entry,
"/", &filename[1]);
}
int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *del_entry)
{
TDB_DATA db_data;
struct locking_key lk;
- TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -475,12 +489,13 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *set_entry,
const struct smb_share_mode_entry *new_entry)
{
TDB_DATA db_data;
struct locking_key lk;
- TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;