summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/blocking.c23
-rw-r--r--source3/smbd/chgpasswd.c8
-rw-r--r--source3/smbd/conn.c23
-rw-r--r--source3/smbd/connection.c8
-rw-r--r--source3/smbd/dir.c69
-rw-r--r--source3/smbd/dosmode.c92
-rw-r--r--source3/smbd/fileio.c2
-rw-r--r--source3/smbd/filename.c1
-rw-r--r--source3/smbd/lanman.c41
-rw-r--r--source3/smbd/mangle_hash2.c6
-rw-r--r--source3/smbd/negprot.c21
-rw-r--r--source3/smbd/nttrans.c960
-rw-r--r--source3/smbd/password.c36
-rw-r--r--source3/smbd/posix_acls.c2
-rw-r--r--source3/smbd/process.c21
-rw-r--r--source3/smbd/reply.c53
-rw-r--r--source3/smbd/server.c157
-rw-r--r--source3/smbd/service.c36
-rw-r--r--source3/smbd/session.c74
-rw-r--r--source3/smbd/sesssetup.c117
-rw-r--r--source3/smbd/ssl.c286
-rw-r--r--source3/smbd/trans2.c88
-rw-r--r--source3/smbd/uid.c86
-rw-r--r--source3/smbd/vfs.c147
24 files changed, 1170 insertions, 1187 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 6623c6df64..d4a53d9a6d 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -282,10 +282,9 @@ static BOOL process_lockread(blocking_lock_record *blr)
status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread,
(SMB_BIG_UINT)startpos, READ_LOCK);
if (NT_STATUS_V(status)) {
- if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
+ if ((errno != EACCES) && (errno != EAGAIN)) {
/*
- * We have other than a "can't get lock"
+ * We have other than a "can't get lock" POSIX
* error. Send an error.
* Return True so we get dequeued.
*/
@@ -349,10 +348,9 @@ static BOOL process_lock(blocking_lock_record *blr)
status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count,
(SMB_BIG_UINT)offset, WRITE_LOCK);
if (NT_STATUS_IS_ERR(status)) {
- if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
+ if((errno != EACCES) && (errno != EAGAIN)) {
/*
- * We have other than a "can't get lock"
+ * We have other than a "can't get lock" POSIX
* error. Send an error.
* Return True so we get dequeued.
*/
@@ -434,13 +432,12 @@ static BOOL process_lockingX(blocking_lock_record *blr)
reply_lockingX_success(blr);
return True;
- } else if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
- /*
- * We have other than a "can't get lock"
- * error. Free any locks we had and return an error.
- * Return True so we get dequeued.
- */
+ } else if ((errno != EACCES) && (errno != EAGAIN)) {
+ /*
+ * We have other than a "can't get lock" POSIX
+ * error. Free any locks we had and return an error.
+ * Return True so we get dequeued.
+ */
blocking_lock_reply_error(blr, status);
return True;
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 9e593b022e..68871deb90 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -167,17 +167,17 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
/* Make slave stdin/out/err of child. */
- if (sys_dup2(slave, STDIN_FILENO) != STDIN_FILENO)
+ if (dup2(slave, STDIN_FILENO) != STDIN_FILENO)
{
DEBUG(3, ("Could not re-direct stdin\n"));
return (False);
}
- if (sys_dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
+ if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
{
DEBUG(3, ("Could not re-direct stdout\n"));
return (False);
}
- if (sys_dup2(slave, STDERR_FILENO) != STDERR_FILENO)
+ if (dup2(slave, STDERR_FILENO) != STDERR_FILENO)
{
DEBUG(3, ("Could not re-direct stderr\n"));
return (False);
@@ -196,9 +196,7 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
}
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
stermios.c_lflag |= ICANON;
-#ifdef ONLCR
stermios.c_oflag &= ~(ONLCR);
-#endif
if (tcsetattr(0, TCSANOW, &stermios) < 0)
{
DEBUG(3, ("could not set attributes of pty\n"));
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index d70e50f899..c0aa447016 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -2,7 +2,6 @@
Unix SMB/CIFS implementation.
Manage connections_struct structures
Copyright (C) Andrew Tridgell 1998
- Copyright (C) Alexander Bokovoy 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -163,25 +162,11 @@ BOOL conn_idle_all(time_t t, int deadtime)
void conn_free(connection_struct *conn)
{
- smb_vfs_handle_struct *handle, *thandle;
- void (*done_fptr)(connection_struct *the_conn);
-
/* Free vfs_connection_struct */
- handle = conn->vfs_private;
- while(handle) {
- /* Close dlopen() handle */
- done_fptr = (void (*)(connection_struct *))sys_dlsym(handle->handle, "vfs_done");
-
- if (done_fptr == NULL) {
- DEBUG(3, ("No vfs_done() symbol found in module with handle %p, ignoring\n", handle->handle));
- } else {
- done_fptr(conn);
- }
- sys_dlclose(handle->handle);
- DLIST_REMOVE(conn->vfs_private, handle);
- thandle = handle->next;
- SAFE_FREE(handle);
- handle = thandle;
+
+ if (conn->dl_handle != NULL) {
+ /* Close dlopen() handle */
+ sys_dlclose(conn->dl_handle);
}
DLIST_REMOVE(Connections, conn);
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 5609c2963d..c9815dbf8c 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -20,6 +20,7 @@
#include "includes.h"
+extern fstring remote_machine;
static TDB_CONTEXT *tdb;
/****************************************************************************
@@ -28,11 +29,6 @@ static TDB_CONTEXT *tdb;
TDB_CONTEXT *conn_tdb_ctx(void)
{
- if (!tdb) {
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644);
- }
-
return tdb;
}
@@ -177,7 +173,7 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
}
crec.start = time(NULL);
- StrnCpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)-1);
+ StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
StrnCpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1);
dbuf.dptr = (char *)&crec;
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 1a18476b75..7dd425ef8a 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -722,62 +722,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
}
/*******************************************************************
-check to see if a user can write a file (and only files, we do not
-check dirs on this one). This is only approximate,
-it is used as part of the "hide unwriteable" option. Don't
-use it for anything security sensitive
-********************************************************************/
-
-static BOOL user_can_write_file(connection_struct *conn, char *name)
-{
- extern struct current_user current_user;
- SMB_STRUCT_STAT ste;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- files_struct *fsp;
- int smb_action;
- int access_mode;
- NTSTATUS status;
- uint32 access_granted;
-
- ZERO_STRUCT(ste);
-
- /*
- * If user is a member of the Admin group
- * we never hide files from them.
- */
-
- if (conn->admin_user)
- return True;
-
- /* If we can't stat it does not show it */
- if (vfs_stat(conn, name, &ste) != 0)
- return False;
-
- /* Pseudo-open the file (note - no fd's created). */
-
- if(S_ISDIR(ste.st_mode))
- return True;
- else
- fsp = open_file_shared1(conn, name, &ste, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
-
- if (!fsp)
- return False;
-
- /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
- close_file(fsp, False);
-
- /* No access if SD get failed. */
- if (!sd_size)
- return False;
-
- return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
- &access_granted, &status);
-}
-
-/*******************************************************************
Open a directory.
********************************************************************/
@@ -837,19 +781,6 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
continue;
}
- /* Honour _hide unwriteable_ option */
- if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) {
- char *entry;
- int ret=0;
-
- if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_write_file(conn, entry);
- SAFE_FREE(entry);
- }
- if (!ret)
- continue;
- }
-
if (used + l > dirp->mallocsize) {
int s = MAX(used+l,used+2000);
char *r;
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 77d8c9cc92..dcffe3aa90 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -115,67 +115,65 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
/****************************************************************************
change a unix mode to a dos mode
****************************************************************************/
-uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
+int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
{
- int result = 0;
+ int result = 0;
- DEBUG(8,("dos_mode: %s\n", path));
+ DEBUG(8,("dos_mode: %s\n", path));
- if ((sbuf->st_mode & S_IWUSR) == 0)
- result |= aRONLY;
-
- if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
- result |= aARCH;
+ if ((sbuf->st_mode & S_IWUSR) == 0)
+ result |= aRONLY;
- if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
- result |= aSYSTEM;
-
- if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
- result |= aHIDDEN;
-
- if (S_ISDIR(sbuf->st_mode))
- result = aDIR | (result & aRONLY);
+ if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
+ result |= aARCH;
- if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) {
- result |= FILE_ATTRIBUTE_SPARSE;
- }
+ if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
+ result |= aSYSTEM;
+
+ if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
+ result |= aHIDDEN;
+
+ if (S_ISDIR(sbuf->st_mode))
+ result = aDIR | (result & aRONLY);
#ifdef S_ISLNK
#if LINKS_READ_ONLY
- if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
- result |= aRONLY;
+ if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
+ result |= aRONLY;
#endif
#endif
- /* hide files with a name starting with a . */
- if (lp_hide_dot_files(SNUM(conn))) {
- char *p = strrchr_m(path,'/');
- if (p)
- p++;
- else
- p = path;
-
- if (p[0] == '.' && p[1] != '.' && p[1] != 0)
- result |= aHIDDEN;
- }
-
- /* Optimization : Only call is_hidden_path if it's not already
- hidden. */
- if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) {
- result |= aHIDDEN;
- }
+ /* hide files with a name starting with a . */
+ if (lp_hide_dot_files(SNUM(conn)))
+ {
+ char *p = strrchr_m(path,'/');
+ if (p)
+ p++;
+ else
+ p = path;
+
+ if (p[0] == '.' && p[1] != '.' && p[1] != 0)
+ result |= aHIDDEN;
+ }
+
+ /* Optimization : Only call is_hidden_path if it's not already
+ hidden. */
+ if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path))
+ {
+ result |= aHIDDEN;
+ }
- DEBUG(8,("dos_mode returning "));
+ DEBUG(8,("dos_mode returning "));
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
-
- DEBUG(8,("\n"));
+ if (result & aHIDDEN) DEBUG(8, ("h"));
+ if (result & aRONLY ) DEBUG(8, ("r"));
+ if (result & aSYSTEM) DEBUG(8, ("s"));
+ if (result & aDIR ) DEBUG(8, ("d"));
+ if (result & aARCH ) DEBUG(8, ("a"));
- return(result);
+ DEBUG(8,("\n"));
+
+ return(result);
}
/*******************************************************************
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 89f05092b4..710ba396d8 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -163,7 +163,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
int write_path = -1;
if (fsp->print_file)
- return print_job_write(SNUM(fsp->conn), fsp->print_jobid, data, n);
+ return print_job_write(fsp->print_jobid, data, n);
if (!fsp->can_write) {
errno = EPERM;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index ce98af4ace..e5f9b7a0ae 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -29,6 +29,7 @@
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
+extern fstring remote_machine;
extern BOOL use_mangled_map;
static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache);
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 8bfad4ab33..996a17e932 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -443,7 +443,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
/* the client expects localtime */
t -= TimeDiff(t);
- PACKI(desc,"W",pjobid_to_rap(snum,queue->job)); /* uJobId */
+ PACKI(desc,"W",queue->job); /* uJobId */
if (uLevel == 1) {
PACKS(desc,"B21",queue->fs_user); /* szUserName */
PACKS(desc,"B",""); /* pad */
@@ -933,7 +933,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
if (!mdrcnt && lp_disable_spoolss())
desc.errcode = ERRbuftoosmall;
- *rdata_len = desc.usedlen;
+ *rdata_len = desc.usedlen;
*rparam_len = 6;
*rparam = REALLOC(*rparam,*rparam_len);
SSVALS(*rparam,0,desc.errcode);
@@ -2181,14 +2181,11 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
char *str1 = param+2;
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
- uint32 jobid;
- int snum;
- int errcode;
+ int jobid, errcode;
extern struct current_user current_user;
WERROR werr = WERR_OK;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ jobid = SVAL(p,0);
/* check it's a supported varient */
if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
@@ -2198,7 +2195,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
*rparam = REALLOC(*rparam,*rparam_len);
*rdata_len = 0;
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(jobid)) {
errcode = NERR_JobNotFound;
goto out;
}
@@ -2207,15 +2204,15 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
switch (function) {
case 81: /* delete */
- if (print_job_delete(&current_user, snum, jobid, &werr))
+ if (print_job_delete(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 82: /* pause */
- if (print_job_pause(&current_user, snum, jobid, &werr))
+ if (print_job_pause(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 83: /* resume */
- if (print_job_resume(&current_user, snum, jobid, &werr))
+ if (print_job_resume(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
}
@@ -2316,14 +2313,12 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
char *str1 = param+2;
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
- uint32 jobid;
- int snum;
+ int jobid;
int uLevel = SVAL(p,2);
int function = SVAL(p,4);
int place, errcode;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ jobid = SVAL(p,0);
*rparam_len = 4;
*rparam = REALLOC(*rparam,*rparam_len);
@@ -2334,7 +2329,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
(!check_printjob_info(&desc,uLevel,str2)))
return(False);
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(jobid)) {
errcode=NERR_JobNotFound;
goto out;
}
@@ -2346,14 +2341,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
/* change job place in the queue,
data gives the new place */
place = SVAL(data,0);
- if (print_job_set_place(snum, jobid, place)) {
+ if (print_job_set_place(jobid, place)) {
errcode=NERR_Success;
}
break;
case 0xb:
/* change print job name, data gives the name */
- if (print_job_set_name(snum, jobid, data)) {
+ if (print_job_set_name(jobid, data)) {
errcode=NERR_Success;
}
break;
@@ -2999,7 +2994,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
int count;
int i;
int snum;
- uint32 jobid;
+ int job;
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
@@ -3016,14 +3011,14 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
if (strcmp(str1,"WWrLh") != 0) return False;
if (!check_printjob_info(&desc,uLevel,str2)) return False;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ job = SVAL(p,0);
+ snum = print_job_snum(job);
if (snum < 0 || !VALID_SNUM(snum)) return(False);
count = print_queue_status(snum,&queue,&status);
for (i = 0; i < count; i++) {
- if (queue[i].job == jobid) break;
+ if (queue[i].job == job) break;
}
if (mdrcnt > 0) {
@@ -3554,7 +3549,7 @@ static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,cha
-const static struct
+struct
{
char *name;
int id;
diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c
index 6b53cc72aa..e2c4b43bc3 100644
--- a/source3/smbd/mangle_hash2.c
+++ b/source3/smbd/mangle_hash2.c
@@ -202,13 +202,13 @@ static BOOL is_mangled_component(const char *name)
M_DEBUG(0,("is_mangled_component %s ?\n", name));
+ /* the best distinguishing characteristic is the ~ */
+ if (name[6] != '~') return False;
+
/* check the length */
len = strlen(name);
if (len > 12 || len < 8) return False;
- /* the best distinguishing characteristic is the ~ */
- if (name[6] != '~') return False;
-
/* check extension */
if (len > 8) {
if (name[8] != '.') return False;
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 2be04fd686..81c2427a00 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -23,6 +23,7 @@
extern int Protocol;
extern int max_recv;
extern fstring global_myworkgroup;
+extern fstring remote_machine;
BOOL global_encrypted_passwords_negotiated = False;
BOOL global_spnego_negotiated = False;
struct auth_context *negprot_global_auth_context = NULL;
@@ -199,11 +200,14 @@ static int negprot_spnego(char *p)
if (lp_security() != SEC_ADS) {
blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
} else {
+ ADS_STRUCT *ads;
+ ads = ads_init_simple();
/* win2000 uses host$@REALM, which we will probably use eventually,
but for now this works */
- asprintf(&principal, "HOST/%s@%s", guid, lp_realm());
+ asprintf(&principal, "HOST/%s@%s", guid, ads->realm);
blob = spnego_gen_negTokenInit(guid, OIDs_krb5, principal);
free(principal);
+ ads_destroy(&ads);
}
memcpy(p, blob.data, blob.length);
len = blob.length;
@@ -284,12 +288,10 @@ static int reply_nt1(char *inbuf, char *outbuf)
if (!negotiate_spnego) {
/* Create a token value and add it to the outgoing packet. */
if (global_encrypted_passwords_negotiated) {
- /* note that we do not send a challenge at all if
- we are using plaintext */
get_challenge(p);
- SSVALS(outbuf,smb_vwv16+1,8);
- p += 8;
}
+ SSVALS(outbuf,smb_vwv16+1,8);
+ p += 8;
p += srvstr_push(outbuf, p, global_myworkgroup, -1,
STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
DEBUG(3,("not using SPNEGO\n"));
@@ -410,17 +412,8 @@ int reply_negprot(connection_struct *conn,
char *p;
int bcc = SVAL(smb_buf(inbuf),-2);
int arch = ARCH_ALL;
-
- static BOOL done_negprot = False;
-
START_PROFILE(SMBnegprot);
- if (done_negprot) {
- END_PROFILE(SMBnegprot);
- exit_server("multiple negprot's are not permitted");
- }
- done_negprot = True;
-
p = smb_buf(inbuf)+1;
while (p < (smb_buf(inbuf) + bcc)) {
Index++;
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index cf69dfddb0..e0a0da7a75 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -28,19 +28,19 @@ extern BOOL case_preserve;
extern BOOL short_case_preserve;
static char *known_nt_pipes[] = {
- "\\LANMAN",
- "\\srvsvc",
- "\\samr",
- "\\wkssvc",
- "\\NETLOGON",
- "\\ntlsa",
- "\\ntsvcs",
- "\\lsass",
- "\\lsarpc",
- "\\winreg",
- "\\spoolss",
- "\\netdfs",
- NULL
+ "\\LANMAN",
+ "\\srvsvc",
+ "\\samr",
+ "\\wkssvc",
+ "\\NETLOGON",
+ "\\ntlsa",
+ "\\ntsvcs",
+ "\\lsass",
+ "\\lsarpc",
+ "\\winreg",
+ "\\spoolss",
+ "\\netdfs",
+ NULL
};
/* Map generic permissions to file object specific permissions */
@@ -62,183 +62,184 @@ struct generic_mapping file_generic_mapping = {
static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_error, char *params,
int paramsize, char *pdata, int datasize)
{
- extern int max_send;
- int data_to_send = datasize;
- int params_to_send = paramsize;
- int useable_space;
- char *pp = params;
- char *pd = pdata;
- int params_sent_thistime, data_sent_thistime, total_sent_thistime;
- int alignment_offset = 3;
- int data_alignment_offset = 0;
+ extern int max_send;
+ int data_to_send = datasize;
+ int params_to_send = paramsize;
+ int useable_space;
+ char *pp = params;
+ char *pd = pdata;
+ int params_sent_thistime, data_sent_thistime, total_sent_thistime;
+ int alignment_offset = 3;
+ int data_alignment_offset = 0;
+
+ /*
+ * Initially set the wcnt area to be 18 - this is true for all
+ * transNT replies.
+ */
+
+ set_message(outbuf,18,0,True);
+
+ if (NT_STATUS_V(nt_error)) {
+ ERROR_NT(nt_error);
+ }
+
+ /*
+ * If there genuinely are no parameters or data to send just send
+ * the empty packet.
+ */
+
+ if(params_to_send == 0 && data_to_send == 0) {
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("send_nt_replies: send_smb failed.");
+ return 0;
+ }
+
+ /*
+ * When sending params and data ensure that both are nicely aligned.
+ * Only do this alignment when there is also data to send - else
+ * can cause NT redirector problems.
+ */
+
+ if (((params_to_send % 4) != 0) && (data_to_send != 0))
+ data_alignment_offset = 4 - (params_to_send % 4);
+
+ /*
+ * Space is bufsize minus Netbios over TCP header minus SMB header.
+ * The alignment_offset is to align the param bytes on a four byte
+ * boundary (2 bytes for data len, one byte pad).
+ * NT needs this to work correctly.
+ */
+
+ useable_space = bufsize - ((smb_buf(outbuf)+
+ alignment_offset+data_alignment_offset) -
+ outbuf);
+
+ /*
+ * useable_space can never be more than max_send minus the
+ * alignment offset.
+ */
+
+ useable_space = MIN(useable_space,
+ max_send - (alignment_offset+data_alignment_offset));
+
+
+ while (params_to_send || data_to_send) {
+
+ /*
+ * Calculate whether we will totally or partially fill this packet.
+ */
+
+ total_sent_thistime = params_to_send + data_to_send +
+ alignment_offset + data_alignment_offset;
+
+ /*
+ * We can never send more than useable_space.
+ */
+
+ total_sent_thistime = MIN(total_sent_thistime, useable_space);
+
+ set_message(outbuf, 18, total_sent_thistime, True);
+
+ /*
+ * Set total params and data to be sent.
+ */
+
+ SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
+ SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
+
+ /*
+ * Calculate how many parameters and data we can fit into
+ * this packet. Parameters get precedence.
+ */
+
+ params_sent_thistime = MIN(params_to_send,useable_space);
+ data_sent_thistime = useable_space - params_sent_thistime;
+ data_sent_thistime = MIN(data_sent_thistime,data_to_send);
+
+ SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
+
+ if(params_sent_thistime == 0) {
+ SIVAL(outbuf,smb_ntr_ParameterOffset,0);
+ SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
+ } else {
+ /*
+ * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
+ * parameter bytes, however the first 4 bytes of outbuf are
+ * the Netbios over TCP header. Thus use smb_base() to subtract
+ * them from the calculation.
+ */
+
+ SIVAL(outbuf,smb_ntr_ParameterOffset,
+ ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
+ /*
+ * Absolute displacement of param bytes sent in this packet.
+ */
+
+ SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
+ }
+
+ /*
+ * Deal with the data portion.
+ */
+
+ SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
+
+ if(data_sent_thistime == 0) {
+ SIVAL(outbuf,smb_ntr_DataOffset,0);
+ SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
+ } else {
+ /*
+ * The offset of the data bytes is the offset of the
+ * parameter bytes plus the number of parameters being sent this time.
+ */
+
+ SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
+ smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
+ SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
+ }
- /*
- * Initially set the wcnt area to be 18 - this is true for all
- * transNT replies.
- */
-
- set_message(outbuf,18,0,True);
-
- if (NT_STATUS_V(nt_error))
- ERROR_NT(nt_error);
-
- /*
- * If there genuinely are no parameters or data to send just send
- * the empty packet.
- */
-
- if(params_to_send == 0 && data_to_send == 0) {
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_nt_replies: send_smb failed.");
- return 0;
- }
-
- /*
- * When sending params and data ensure that both are nicely aligned.
- * Only do this alignment when there is also data to send - else
- * can cause NT redirector problems.
- */
-
- if (((params_to_send % 4) != 0) && (data_to_send != 0))
- data_alignment_offset = 4 - (params_to_send % 4);
-
- /*
- * Space is bufsize minus Netbios over TCP header minus SMB header.
- * The alignment_offset is to align the param bytes on a four byte
- * boundary (2 bytes for data len, one byte pad).
- * NT needs this to work correctly.
- */
-
- useable_space = bufsize - ((smb_buf(outbuf)+
- alignment_offset+data_alignment_offset) -
- outbuf);
-
- /*
- * useable_space can never be more than max_send minus the
- * alignment offset.
- */
-
- useable_space = MIN(useable_space,
- max_send - (alignment_offset+data_alignment_offset));
+ /*
+ * Copy the param bytes into the packet.
+ */
+ if(params_sent_thistime)
+ memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
+
+ /*
+ * Copy in the data bytes
+ */
- while (params_to_send || data_to_send) {
-
- /*
- * Calculate whether we will totally or partially fill this packet.
- */
-
- total_sent_thistime = params_to_send + data_to_send +
- alignment_offset + data_alignment_offset;
-
- /*
- * We can never send more than useable_space.
- */
-
- total_sent_thistime = MIN(total_sent_thistime, useable_space);
-
- set_message(outbuf, 18, total_sent_thistime, True);
-
- /*
- * Set total params and data to be sent.
- */
-
- SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
- SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
-
- /*
- * Calculate how many parameters and data we can fit into
- * this packet. Parameters get precedence.
- */
-
- params_sent_thistime = MIN(params_to_send,useable_space);
- data_sent_thistime = useable_space - params_sent_thistime;
- data_sent_thistime = MIN(data_sent_thistime,data_to_send);
-
- SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
-
- if(params_sent_thistime == 0) {
- SIVAL(outbuf,smb_ntr_ParameterOffset,0);
- SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
- } else {
- /*
- * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
- * parameter bytes, however the first 4 bytes of outbuf are
- * the Netbios over TCP header. Thus use smb_base() to subtract
- * them from the calculation.
- */
-
- SIVAL(outbuf,smb_ntr_ParameterOffset,
- ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
- /*
- * Absolute displacement of param bytes sent in this packet.
- */
-
- SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
- }
-
- /*
- * Deal with the data portion.
- */
-
- SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
-
- if(data_sent_thistime == 0) {
- SIVAL(outbuf,smb_ntr_DataOffset,0);
- SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
- } else {
- /*
- * The offset of the data bytes is the offset of the
- * parameter bytes plus the number of parameters being sent this time.
- */
-
- SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
- smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
- SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
- }
-
- /*
- * Copy the param bytes into the packet.
- */
-
- if(params_sent_thistime)
- memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
-
- /*
- * Copy in the data bytes
- */
-
- if(data_sent_thistime)
- memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
- data_alignment_offset,pd,data_sent_thistime);
+ if(data_sent_thistime)
+ memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
+ data_alignment_offset,pd,data_sent_thistime);
- DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
- params_sent_thistime, data_sent_thistime, useable_space));
- DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
- params_to_send, data_to_send, paramsize, datasize));
+ DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
+ params_sent_thistime, data_sent_thistime, useable_space));
+ DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
+ params_to_send, data_to_send, paramsize, datasize));
- /* Send the packet */
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_nt_replies: send_smb failed.");
+ /* Send the packet */
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("send_nt_replies: send_smb failed.");
- pp += params_sent_thistime;
- pd += data_sent_thistime;
+ pp += params_sent_thistime;
+ pd += data_sent_thistime;
- params_to_send -= params_sent_thistime;
- data_to_send -= data_sent_thistime;
+ params_to_send -= params_sent_thistime;
+ data_to_send -= data_sent_thistime;
- /*
- * Sanity check
- */
+ /*
+ * Sanity check
+ */
- if(params_to_send < 0 || data_to_send < 0) {
- DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
- params_to_send, data_to_send));
- return -1;
- }
- }
+ if(params_to_send < 0 || data_to_send < 0) {
+ DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
+ params_to_send, data_to_send));
+ return -1;
+ }
+ }
- return 0;
+ return 0;
}
/****************************************************************************
@@ -851,7 +852,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
p += 8;
SIVAL(p,0,fmode); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, get_allocation_size(&sbuf));
+ SOFF_T(p, 0, SMB_ROUNDUP_ALLOCATION(file_len));
p += 8;
SOFF_T(p,0,file_len);
p += 12;
@@ -1295,7 +1296,7 @@ static int call_nt_transact_create(connection_struct *conn,
p += 8;
SIVAL(p,0,fmode); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, get_allocation_size(&sbuf));
+ SOFF_T(p, 0, SMB_ROUNDUP_ALLOCATION(file_len));
p += 8;
SOFF_T(p,0,file_len);
@@ -1310,7 +1311,6 @@ static int call_nt_transact_create(connection_struct *conn,
/****************************************************************************
Reply to a NT CANCEL request.
****************************************************************************/
-
int reply_ntcancel(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -1332,7 +1332,6 @@ int reply_ntcancel(connection_struct *conn,
/****************************************************************************
Reply to an unsolicited SMBNTtranss - just ignore it!
****************************************************************************/
-
int reply_nttranss(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -1346,7 +1345,6 @@ int reply_nttranss(connection_struct *conn,
Reply to a notify change - queue the request and
don't allow a directory to be opened.
****************************************************************************/
-
static int call_nt_transact_notify_change(connection_struct *conn,
char *inbuf, char *outbuf, int length,
int bufsize,
@@ -1447,107 +1445,107 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
int length, int bufsize,
char **ppsetup, char **ppparams, char **ppdata)
{
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
- char *params = *ppparams;
- char *data = *ppdata;
- prs_struct pd;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- TALLOC_CTX *mem_ctx;
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+ char *params = *ppparams;
+ char *data = *ppdata;
+ prs_struct pd;
+ SEC_DESC *psd = NULL;
+ size_t sd_size;
+ TALLOC_CTX *mem_ctx;
- files_struct *fsp = file_fsp(params,0);
+ files_struct *fsp = file_fsp(params,0);
- if(!fsp)
- return ERROR_DOS(ERRDOS,ERRbadfid);
+ if(!fsp)
+ return ERROR_DOS(ERRDOS,ERRbadfid);
- DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
+ DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
- params = Realloc(*ppparams, 4);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ params = Realloc(*ppparams, 4);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
- *ppparams = params;
+ *ppparams = params;
- if ((mem_ctx = talloc_init()) == NULL) {
- DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
- return ERROR_DOS(ERRDOS,ERRnomem);
- }
+ if ((mem_ctx = talloc_init()) == NULL) {
+ DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ }
- /*
- * Get the permissions to return.
- */
+ /*
+ * Get the permissions to return.
+ */
- if (!lp_nt_acl_support(SNUM(conn)))
- sd_size = get_null_nt_acl(mem_ctx, &psd);
- else
- sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
+ if (!lp_nt_acl_support(SNUM(conn)))
+ sd_size = get_null_nt_acl(mem_ctx, &psd);
+ else
+ sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
- if (sd_size == 0) {
- talloc_destroy(mem_ctx);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ if (sd_size == 0) {
+ talloc_destroy(mem_ctx);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %d.\n",(int)sd_size));
+ DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %d.\n",(int)sd_size));
- SIVAL(params,0,(uint32)sd_size);
+ SIVAL(params,0,(uint32)sd_size);
- if(max_data_count < sd_size) {
+ if(max_data_count < sd_size) {
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
- params, 4, *ppdata, 0);
- talloc_destroy(mem_ctx);
- return -1;
- }
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
+ params, 4, *ppdata, 0);
+ talloc_destroy(mem_ctx);
+ return -1;
+ }
- /*
- * Allocate the data we will point this at.
- */
+ /*
+ * Allocate the data we will point this at.
+ */
- data = Realloc(*ppdata, sd_size);
- if(data == NULL) {
- talloc_destroy(mem_ctx);
- return ERROR_DOS(ERRDOS,ERRnomem);
- }
+ data = Realloc(*ppdata, sd_size);
+ if(data == NULL) {
+ talloc_destroy(mem_ctx);
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ }
- *ppdata = data;
+ *ppdata = data;
- memset(data, '\0', sd_size);
+ memset(data, '\0', sd_size);
- /*
- * Init the parse struct we will marshall into.
- */
+ /*
+ * Init the parse struct we will marshall into.
+ */
- prs_init(&pd, 0, mem_ctx, MARSHALL);
+ prs_init(&pd, 0, mem_ctx, MARSHALL);
- /*
- * Setup the prs_struct to point at the memory we just
- * allocated.
- */
+ /*
+ * Setup the prs_struct to point at the memory we just
+ * allocated.
+ */
- prs_give_memory( &pd, data, (uint32)sd_size, False);
+ prs_give_memory( &pd, data, (uint32)sd_size, False);
- /*
- * Finally, linearize into the outgoing buffer.
- */
+ /*
+ * Finally, linearize into the outgoing buffer.
+ */
- if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
- DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
+ if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
+ DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
security descriptor.\n"));
- /*
- * Return access denied for want of a better error message..
- */
- talloc_destroy(mem_ctx);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ /*
+ * Return access denied for want of a better error message..
+ */
+ talloc_destroy(mem_ctx);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- /*
- * Now we can delete the security descriptor.
- */
+ /*
+ * Now we can delete the security descriptor.
+ */
- talloc_destroy(mem_ctx);
+ talloc_destroy(mem_ctx);
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);
- return -1;
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);
+ return -1;
}
/****************************************************************************
@@ -1594,263 +1592,233 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
}
/****************************************************************************
- Reply to NT IOCTL
+ Reply to IOCTL - not implemented - no plans.
****************************************************************************/
+
static int call_nt_transact_ioctl(connection_struct *conn,
char *inbuf, char *outbuf, int length,
int bufsize,
- char **ppsetup, int setup_count,
- char **ppparams, int parameter_count,
- char **ppdata, int data_count)
+ char **ppsetup, char **ppparams, char **ppdata)
{
- unsigned fnum, control;
- static BOOL logged_message;
+ static BOOL logged_message = False;
- if (setup_count != 8) {
- DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ if(!logged_message) {
+ DEBUG(3,("call_nt_transact_ioctl: Currently not implemented.\n"));
+ logged_message = True; /* Only print this once... */
}
-
- fnum = SVAL(*ppsetup, 4);
- control = IVAL(*ppsetup, 0);
-
- DEBUG(6,("call_nt_transact_ioctl: fnum=%d control=0x%x\n",
- fnum, control));
-
- switch (control) {
- case NTIOCTL_SET_SPARSE:
- /* pretend this succeeded - tho strictly we should
- mark the file sparse (if the local fs supports it)
- so we can know if we need to pre-allocate or not */
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
- return -1;
-
- default:
- if (!logged_message) {
- logged_message = True; /* Only print this once... */
- DEBUG(3,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
- control));
- }
- }
-
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ return ERROR_DOS(ERRSRV,ERRnosupport);
}
/****************************************************************************
Reply to a SMBNTtrans.
****************************************************************************/
-
int reply_nttrans(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+ char *inbuf,char *outbuf,int length,int bufsize)
{
- int outsize = 0;
+ int outsize = 0;
#if 0 /* Not used. */
- uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
- uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+ uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
+ uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
#endif /* Not used. */
- uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
- uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
- uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
- uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
- uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
- uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
- uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
- uint16 function_code = SVAL( inbuf, smb_nt_Function);
- char *params = NULL, *data = NULL, *setup = NULL;
- uint32 num_params_sofar, num_data_sofar;
- START_PROFILE(SMBnttrans);
-
- if(global_oplock_break &&
- ((function_code == NT_TRANSACT_CREATE) ||
- (function_code == NT_TRANSACT_RENAME))) {
- /*
- * Queue this open message as we are the process of an oplock break.
- */
-
- DEBUG(2,("reply_nttrans: queueing message code 0x%x \
-due to being in oplock break state.\n", (unsigned int)function_code ));
-
- push_oplock_pending_smb_message( inbuf, length);
- END_PROFILE(SMBnttrans);
- return -1;
- }
-
- if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRaccess);
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- /*
- * All nttrans messages we handle have smb_wct == 19 + setup_count.
- * Ensure this is so as a sanity check.
- */
-
- if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
- DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
- CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRerror);
- }
+ uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
+ uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
+ uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
+ uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
+ uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
+ uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
+ uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
+ uint16 function_code = SVAL( inbuf, smb_nt_Function);
+ char *params = NULL, *data = NULL, *setup = NULL;
+ uint32 num_params_sofar, num_data_sofar;
+ START_PROFILE(SMBnttrans);
+
+ if(global_oplock_break && (function_code == NT_TRANSACT_CREATE)) {
+ /*
+ * Queue this open message as we are the process of an oplock break.
+ */
+
+ DEBUG(2,("reply_nttrans: queueing message NT_TRANSACT_CREATE \
+due to being in oplock break state.\n" ));
+
+ push_oplock_pending_smb_message( inbuf, length);
+ END_PROFILE(SMBnttrans);
+ return -1;
+ }
+
+ if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRSRV,ERRaccess);
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+
+ /*
+ * All nttrans messages we handle have smb_wct == 19 + setup_count.
+ * Ensure this is so as a sanity check.
+ */
+
+ if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
+ DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
+ CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
- /* Allocate the space for the setup, the maximum needed parameters and data */
-
- if(setup_count > 0)
- setup = (char *)malloc(setup_count);
- if (total_parameter_count > 0)
- params = (char *)malloc(total_parameter_count);
- if (total_data_count > 0)
- data = (char *)malloc(total_data_count);
+ /* Allocate the space for the setup, the maximum needed parameters and data */
+
+ if(setup_count > 0)
+ setup = (char *)malloc(setup_count);
+ if (total_parameter_count > 0)
+ params = (char *)malloc(total_parameter_count);
+ if (total_data_count > 0)
+ data = (char *)malloc(total_data_count);
- if ((total_parameter_count && !params) || (total_data_count && !data) ||
- (setup_count && !setup)) {
- SAFE_FREE(setup);
- SAFE_FREE(params);
- SAFE_FREE(data);
- DEBUG(0,("reply_nttrans : Out of memory\n"));
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRDOS,ERRnomem);
- }
-
- /* Copy the param and data bytes sent with this request into the params buffer */
- num_params_sofar = parameter_count;
- num_data_sofar = data_count;
-
- if (parameter_count > total_parameter_count || data_count > total_data_count)
- exit_server("reply_nttrans: invalid sizes in packet.");
-
- if(setup) {
- memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
- DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
- dump_data(10, setup, setup_count);
- }
- if(params) {
- memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
- DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
- dump_data(10, params, parameter_count);
- }
- if(data) {
- memcpy( data, smb_base(inbuf) + data_offset, data_count);
- DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
- dump_data(10, data, data_count);
- }
-
- if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
- /* We need to send an interim response then receive the rest
- of the parameter/data bytes */
- outsize = set_message(outbuf,0,0,True);
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_nttrans: send_smb failed.");
-
- while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
- BOOL ret;
-
- ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
-
- if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
- outsize = set_message(outbuf,0,0,True);
- if(ret) {
- DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
- } else {
- DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
- (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
- }
- SAFE_FREE(params);
- SAFE_FREE(data);
- SAFE_FREE(setup);
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- /* Revise total_params and total_data in case they have changed downwards */
- total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
- total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
- num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
- num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
- if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
- exit_server("reply_nttrans2: data overflow in secondary nttrans packet");
-
- memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)],
- smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
- memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
- smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
- }
- }
-
- if (Protocol >= PROTOCOL_NT1)
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
-
- /* Now we must call the relevant NT_TRANS function */
- switch(function_code) {
- case NT_TRANSACT_CREATE:
- START_PROFILE_NESTED(NT_transact_create);
- outsize = call_nt_transact_create(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
- END_PROFILE_NESTED(NT_transact_create);
- break;
- case NT_TRANSACT_IOCTL:
- START_PROFILE_NESTED(NT_transact_ioctl);
- outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, parameter_count,
- &data, data_count);
- END_PROFILE_NESTED(NT_transact_ioctl);
- break;
- case NT_TRANSACT_SET_SECURITY_DESC:
- START_PROFILE_NESTED(NT_transact_set_security_desc);
- outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
- END_PROFILE_NESTED(NT_transact_set_security_desc);
- break;
- case NT_TRANSACT_NOTIFY_CHANGE:
- START_PROFILE_NESTED(NT_transact_notify_change);
- outsize = call_nt_transact_notify_change(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
- END_PROFILE_NESTED(NT_transact_notify_change);
- break;
- case NT_TRANSACT_RENAME:
- START_PROFILE_NESTED(NT_transact_rename);
- outsize = call_nt_transact_rename(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
- END_PROFILE_NESTED(NT_transact_rename);
- break;
-
- case NT_TRANSACT_QUERY_SECURITY_DESC:
- START_PROFILE_NESTED(NT_transact_query_security_desc);
- outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
- END_PROFILE_NESTED(NT_transact_query_security_desc);
- break;
- default:
- /* Error in request */
- DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
- SAFE_FREE(setup);
- SAFE_FREE(params);
- SAFE_FREE(data);
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- /* As we do not know how many data packets will need to be
- returned here the various call_nt_transact_xxxx calls
- must send their own. Thus a call_nt_transact_xxxx routine only
- returns a value other than -1 when it wants to send
- an error packet.
- */
-
+ if ((total_parameter_count && !params) || (total_data_count && !data) ||
+ (setup_count && !setup)) {
SAFE_FREE(setup);
SAFE_FREE(params);
SAFE_FREE(data);
+ DEBUG(0,("reply_nttrans : Out of memory\n"));
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ }
+
+ /* Copy the param and data bytes sent with this request into
+ the params buffer */
+ num_params_sofar = parameter_count;
+ num_data_sofar = data_count;
+
+ if (parameter_count > total_parameter_count || data_count > total_data_count)
+ exit_server("reply_nttrans: invalid sizes in packet.");
+
+ if(setup) {
+ memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
+ DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
+ dump_data(10, setup, setup_count);
+ }
+ if(params) {
+ memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
+ DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
+ dump_data(10, params, parameter_count);
+ }
+ if(data) {
+ memcpy( data, smb_base(inbuf) + data_offset, data_count);
+ DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
+ dump_data(10, data, data_count);
+ }
+
+ if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
+ /* We need to send an interim response then receive the rest
+ of the parameter/data bytes */
+ outsize = set_message(outbuf,0,0,True);
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_nttrans: send_smb failed.");
+
+ while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
+ BOOL ret;
+
+ ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+ if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
+ outsize = set_message(outbuf,0,0,True);
+ if(ret) {
+ DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
+ } else {
+ DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
+ (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
+ }
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ SAFE_FREE(setup);
END_PROFILE(SMBnttrans);
- return outsize; /* If a correct response was needed the call_nt_transact_xxxx
- calls have already sent it. If outsize != -1 then it is
- returning an error packet. */
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ /* Revise total_params and total_data in case they have changed downwards */
+ total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
+ total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
+ num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
+ num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
+ if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
+ exit_server("reply_nttrans2: data overflow in secondary nttrans packet");
+
+ memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)],
+ smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
+ memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
+ smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
+ }
+ }
+
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
+
+ /* Now we must call the relevant NT_TRANS function */
+ switch(function_code) {
+ case NT_TRANSACT_CREATE:
+ START_PROFILE_NESTED(NT_transact_create);
+ outsize = call_nt_transact_create(conn, inbuf, outbuf, length, bufsize,
+ &setup, &params, &data);
+ END_PROFILE_NESTED(NT_transact_create);
+ break;
+ case NT_TRANSACT_IOCTL:
+ START_PROFILE_NESTED(NT_transact_ioctl);
+ outsize = call_nt_transact_ioctl(conn,
+ inbuf, outbuf, length, bufsize,
+ &setup, &params, &data);
+ END_PROFILE_NESTED(NT_transact_ioctl);
+ break;
+ case NT_TRANSACT_SET_SECURITY_DESC:
+ START_PROFILE_NESTED(NT_transact_set_security_desc);
+ outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf,
+ length, bufsize,
+ &setup, &params, &data);
+ END_PROFILE_NESTED(NT_transact_set_security_desc);
+ break;
+ case NT_TRANSACT_NOTIFY_CHANGE:
+ START_PROFILE_NESTED(NT_transact_notify_change);
+ outsize = call_nt_transact_notify_change(conn, inbuf, outbuf,
+ length, bufsize,
+ &setup, &params, &data);
+ END_PROFILE_NESTED(NT_transact_notify_change);
+ break;
+ case NT_TRANSACT_RENAME:
+ START_PROFILE_NESTED(NT_transact_rename);
+ outsize = call_nt_transact_rename(conn, inbuf, outbuf, length,
+ bufsize,
+ &setup, &params, &data);
+ END_PROFILE_NESTED(NT_transact_rename);
+ break;
+
+ case NT_TRANSACT_QUERY_SECURITY_DESC:
+ START_PROFILE_NESTED(NT_transact_query_security_desc);
+ outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf,
+ length, bufsize,
+ &setup, &params, &data);
+ END_PROFILE_NESTED(NT_transact_query_security_desc);
+ break;
+ default:
+ /* Error in request */
+ DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
+ SAFE_FREE(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ /* As we do not know how many data packets will need to be
+ returned here the various call_nt_transact_xxxx calls
+ must send their own. Thus a call_nt_transact_xxxx routine only
+ returns a value other than -1 when it wants to send
+ an error packet.
+ */
+
+ SAFE_FREE(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ END_PROFILE(SMBnttrans);
+ return outsize; /* If a correct response was needed the call_nt_transact_xxxx
+ calls have already sent it. If outsize != -1 then it is
+ returning an error packet. */
}
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index cfac7cf695..82c0cef77d 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -90,6 +90,29 @@ void invalidate_all_vuids(void)
}
/****************************************************************************
+return a validated username
+****************************************************************************/
+char *validated_username(uint16 vuid)
+{
+ user_struct *vuser = get_valid_user_struct(vuid);
+ if (vuser == NULL)
+ return 0;
+ return(vuser->user.unix_name);
+}
+
+/****************************************************************************
+return a validated domain
+****************************************************************************/
+char *validated_domain(uint16 vuid)
+{
+ user_struct *vuser = get_valid_user_struct(vuid);
+ if (vuser == NULL)
+ return 0;
+ return(vuser->user.domain);
+}
+
+
+/****************************************************************************
Create the SID list for this user.
****************************************************************************/
@@ -184,7 +207,7 @@ has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
-int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
+int register_vuid(auth_serversupplied_info *server_info, char *smb_name)
{
user_struct *vuser = NULL;
uid_t uid;
@@ -274,7 +297,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
/* Create an NT_USER_TOKEN struct for this user. */
vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, vuser->guest, server_info->ptok);
- DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid));
+ DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name));
next_vuid++;
num_validated_vuids++;
@@ -288,9 +311,8 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
}
/* Register a home dir service for this user */
- if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) {
- DEBUG(3, ("Adding/updating homes service for user '%s' using home direcotry: '%s'\n",
- vuser->user.unix_name, vuser->unix_homedir));
+ if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)
+ && (lp_servicenumber(vuser->user.unix_name) < 0)) {
vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir);
} else {
vuser->homes_snum = -1;
@@ -303,7 +325,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
/****************************************************************************
add a name to the session users list
****************************************************************************/
-void add_session_user(const char *user)
+void add_session_user(char *user)
{
fstring suser;
StrnCpy(suser,user,sizeof(suser)-1);
@@ -351,7 +373,7 @@ BOOL user_ok(const char *user,int snum)
if (valid) str_list_free (&valid);
if (ret && lp_onlyuser(snum)) {
- char **user_list = str_list_make (lp_username(snum), NULL);
+ char **user_list = str_list_make (lp_username(snum));
if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) {
ret = user_in_list(user, user_list);
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 043e33e836..85818d524a 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2296,7 +2296,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
switch(tagtype) {
case SMB_ACL_USER_OBJ:
perms = unix_perms_to_acl_perms(mode, S_IRUSR, S_IWUSR, S_IXUSR);
- break;
+ break;
case SMB_ACL_GROUP_OBJ:
perms = unix_perms_to_acl_perms(mode, S_IRGRP, S_IWGRP, S_IXGRP);
break;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 55234ec896..43d3c6c531 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -152,7 +152,7 @@ static void async_processing(char *buffer, int buffer_len)
Returns False on timeout or error.
Else returns True.
-The timeout is in milliseconds
+The timeout is in milli seconds
****************************************************************************/
static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
@@ -341,9 +341,9 @@ force write permissions on print services.
functions. Any message that has a NULL function is unimplemented -
please feel free to contribute implementations!
*/
-const static struct smb_message_struct
+static struct smb_message_struct
{
- const char *name;
+ char *name;
int (*fn)(connection_struct *conn, char *, char *, int, int);
int flags;
}
@@ -386,7 +386,7 @@ const static struct smb_message_struct
/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
-/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
+/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
/* 0x26 */ { "SMBtranss",NULL,AS_USER | CAN_IPC},
/* 0x27 */ { "SMBioctl",reply_ioctl,0},
/* 0x28 */ { "SMBioctls",NULL,AS_USER},
@@ -399,7 +399,7 @@ const static struct smb_message_struct
/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
/* 0x30 */ { NULL, NULL, 0 },
/* 0x31 */ { NULL, NULL, 0 },
-/* 0x32 */ { "SMBtrans2", reply_trans2, AS_USER | CAN_IPC },
+/* 0x32 */ { "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK | CAN_IPC },
/* 0x33 */ { "SMBtranss2", reply_transs2, AS_USER},
/* 0x34 */ { "SMBfindclose", reply_findclose,AS_USER},
/* 0x35 */ { "SMBfindnclose", reply_findnclose, AS_USER},
@@ -611,7 +611,7 @@ const static struct smb_message_struct
/*******************************************************************
dump a prs to a file
********************************************************************/
-static void smb_dump(const char *name, int type, char *data, ssize_t len)
+static void smb_dump(char *name, int type, char *data, ssize_t len)
{
int fd, i;
pstring fname;
@@ -896,7 +896,7 @@ void process_smb(char *inbuf, char *outbuf)
/****************************************************************************
return a string containing the function name of a SMB command
****************************************************************************/
-const char *smb_fn_name(int type)
+char *smb_fn_name(int type)
{
static char *unknown_name = "SMBunknown";
@@ -1228,6 +1228,13 @@ void smbd_process(void)
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+ /* re-initialise the timezone */
+ TimeInit();
+
+ /* register our message handlers */
+ message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis);
+ talloc_init_named("dummy!");
+
while (True) {
int deadtime = lp_deadtime()*60;
int select_timeout = setup_select_timeout();
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index c6a082d7d8..0ccdf7c241 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -38,6 +38,7 @@ extern pstring global_myname;
extern int global_oplock_break;
unsigned int smb_echo_count = 0;
+extern fstring remote_machine;
extern BOOL global_encrypted_passwords_negotiated;
@@ -52,11 +53,10 @@ int reply_special(char *inbuf,char *outbuf)
int msg_flags = CVAL(inbuf,1);
pstring name1,name2;
+ extern fstring local_machine;
int len;
char name_type = 0;
- static BOOL already_got_session = False;
-
*name1 = *name2 = 0;
memset(outbuf,'\0',smb_size);
@@ -65,11 +65,6 @@ int reply_special(char *inbuf,char *outbuf)
switch (msg_type) {
case 0x81: /* session request */
-
- if (already_got_session) {
- exit_server("multiple session request not permitted");
- }
-
SCVAL(outbuf,0,0x82);
SCVAL(outbuf,3,0);
if (name_len(inbuf+4) > 50 ||
@@ -82,19 +77,24 @@ int reply_special(char *inbuf,char *outbuf)
DEBUG(2,("netbios connect: name1=%s name2=%s\n",
name1,name2));
- name1[15] = 0;
+ fstrcpy(remote_machine,name2);
+ remote_machine[15] = 0;
+ trim_string(remote_machine," "," ");
+ strlower(remote_machine);
+ alpha_strcpy(remote_machine,remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
- len = strlen(name2);
+ fstrcpy(local_machine,name1);
+ len = strlen(local_machine);
if (len == 16) {
- name_type = name2[15];
- name2[15] = 0;
+ name_type = local_machine[15];
+ local_machine[15] = 0;
}
-
- set_local_machine_name(name1);
- set_remote_machine_name(name2);
+ trim_string(local_machine," "," ");
+ strlower(local_machine);
+ alpha_strcpy(local_machine,local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
DEBUG(2,("netbios connect: local=%s remote=%s\n",
- get_local_machine_name(), get_remote_machine_name() ));
+ local_machine, remote_machine ));
if (name_type == 'R') {
/* We are being asked for a pathworks session ---
@@ -107,7 +107,7 @@ int reply_special(char *inbuf,char *outbuf)
of possibly valid usernames if we are operating
in share mode security */
if (lp_security() == SEC_SHARE) {
- add_session_user(get_remote_machine_name());
+ add_session_user(remote_machine);
}
reload_services(True);
@@ -115,7 +115,6 @@ int reply_special(char *inbuf,char *outbuf)
claim_connection(NULL,"",MAXSTATUS,True);
- already_got_session = True;
break;
case 0x89: /* session keepalive request
@@ -149,8 +148,7 @@ int reply_special(char *inbuf,char *outbuf)
int reply_tcon(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- const char *service;
- pstring service_buf;
+ pstring service;
pstring password;
pstring dev;
int outsize = 0;
@@ -162,19 +160,17 @@ int reply_tcon(connection_struct *conn,
START_PROFILE(SMBtcon);
- *service_buf = *password = *dev = 0;
+ *service = *password = *dev = 0;
p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service), STR_TERMINATE) + 1;
+ p += srvstr_pull_buf(inbuf, service, p, sizeof(service), STR_TERMINATE) + 1;
pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
p += pwlen;
p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
- p = strrchr_m(service_buf,'\\');
+ p = strrchr_m(service,'\\');
if (p) {
- service = p+1;
- } else {
- service = service_buf;
+ pstrcpy(service, p+1);
}
password_blob = data_blob(password, pwlen+1);
@@ -358,13 +354,10 @@ int reply_ioctl(connection_struct *conn,
switch (ioctl_code)
{
case IOCTL_QUERY_JOB_INFO:
- {
- uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid);
- SSVAL(p,0,rap_jobid); /* Job number */
+ SSVAL(p,0,fsp->print_jobid); /* Job number */
srvstr_push(outbuf, p+2, global_myname, 15, STR_TERMINATE|STR_ASCII);
srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
break;
- }
}
END_PROFILE(SMBioctl);
@@ -2751,8 +2744,6 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
- RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
-
status = mkdir_internal(conn, directory);
if (!NT_STATUS_IS_OK(status))
return ERROR_NT(status);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index b2b905cec3..6f0d0238b0 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -38,6 +38,8 @@ extern pstring user_socket_options;
extern int dcelogin_atmost_once;
#endif /* WITH_DFS */
+extern fstring remote_machine;
+
/* really we should have a top level context structure that has the
client file descriptor as an element. That would require a major rewrite :(
@@ -131,7 +133,7 @@ static BOOL open_sockets_inetd(void)
smbd_set_server_fd(dup(0));
/* close our standard file descriptors */
- close_low_fds(False); /* Don't close stderr */
+ close_low_fds();
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
set_socket_options(smbd_server_fd(), user_socket_options);
@@ -149,15 +151,13 @@ static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len)
Open the socket communication.
****************************************************************************/
-static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
+static BOOL open_sockets(BOOL is_daemon,int port)
{
int num_interfaces = iface_count();
- int num_sockets = 0;
int fd_listenset[FD_SETSIZE];
fd_set listen_set;
int s;
int i;
- char *ports;
if (!is_daemon) {
return open_sockets_inetd();
@@ -176,106 +176,73 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
/* Stop zombies */
CatchChild();
-
+
+
FD_ZERO(&listen_set);
- /* use a reasonable default set of ports - listing on 445 and 139 */
- if (!smb_ports) {
- ports = lp_smb_ports();
- if (!ports || !*ports) {
- ports = SMB_PORTS;
- }
- ports = strdup(ports);
- } else {
- ports = strdup(smb_ports);
- }
-
- if (lp_interfaces() && lp_bind_interfaces_only()) {
+ if(lp_interfaces() && lp_bind_interfaces_only()) {
/* We have been given an interfaces line, and been
told to only bind to those interfaces. Create a
socket per interface and bind to only these.
*/
+ if(num_interfaces > FD_SETSIZE) {
+ DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
+max can be %d\n",
+ num_interfaces, FD_SETSIZE));
+ return False;
+ }
+
/* Now open a listen socket for each of the
interfaces. */
for(i = 0; i < num_interfaces; i++) {
struct in_addr *ifip = iface_n_ip(i);
- fstring tok;
- char *ptr;
-
+
if(ifip == NULL) {
- DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
+ DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
continue;
}
+ s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
+ if(s == -1)
+ return False;
- for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0) continue;
- s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
- if(s == -1)
- return False;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
- if (listen(s, 5) == -1) {
- DEBUG(0,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
- FD_SET(s,&listen_set);
-
- num_sockets++;
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
- }
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("listen: %s\n",strerror(errno)));
+ close(s);
+ return False;
}
+ FD_SET(s,&listen_set);
}
} else {
/* Just bind to 0.0.0.0 - accept connections
from anywhere. */
-
- fstring tok;
- char *ptr;
-
num_interfaces = 1;
- for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0) continue;
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,
- interpret_addr(lp_socket_address()),True);
- if (s == -1)
- return(False);
+ /* open an incoming socket */
+ s = open_socket_in(SOCK_STREAM, port, 0,
+ interpret_addr(lp_socket_address()),True);
+ if (s == -1)
+ return(False);
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- if (listen(s, 5) == -1) {
- DEBUG(0,("open_sockets_smbd: listen: %s\n",
- strerror(errno)));
- close(s);
- return False;
- }
-
- fd_listenset[num_sockets] = s;
- FD_SET(s,&listen_set);
-
- num_sockets++;
-
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
- }
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
+
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("open_sockets: listen: %s\n",
+ strerror(errno)));
+ close(s);
+ return False;
}
+
+ fd_listenset[0] = s;
+ FD_SET(s,&listen_set);
}
- SAFE_FREE(ports);
-
/* Listen to messages */
message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
@@ -326,7 +293,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
socklen_t in_addrlen = sizeof(addr);
s = -1;
- for(i = 0; i < num_sockets; i++) {
+ for(i = 0; i < num_interfaces; i++) {
if(FD_ISSET(fd_listenset[i],&lfds)) {
s = fd_listenset[i];
/* Clear this so we don't look
@@ -342,7 +309,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
continue;
if (smbd_server_fd() == -1) {
- DEBUG(0,("open_sockets_smbd: accept: %s\n",
+ DEBUG(0,("open_sockets: accept: %s\n",
strerror(errno)));
continue;
}
@@ -351,21 +318,17 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
/* Child code ... */
/* close the listening socket(s) */
- for(i = 0; i < num_sockets; i++)
+ for(i = 0; i < num_interfaces; i++)
close(fd_listenset[i]);
/* close our standard file
descriptors */
- close_low_fds(False);
+ close_low_fds();
am_parent = 0;
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
set_socket_options(smbd_server_fd(),user_socket_options);
- /* this is needed so that we get decent entries
- in smbstatus for port 445 connects */
- set_remote_machine_name(get_socket_addr(smbd_server_fd()));
-
/* Reset global variables in util.c so
that client substitutions will be
done correctly in the process. */
@@ -419,6 +382,8 @@ BOOL reload_services(BOOL test)
{
BOOL ret;
+ set_register_printer_fn();
+
if (lp_loaded()) {
pstring fname;
pstrcpy(fname,lp_configfile());
@@ -646,7 +611,7 @@ static void usage(char *pname)
BOOL is_daemon = False;
BOOL interactive = False;
BOOL specified_logfile = False;
- char *ports = NULL;
+ int port = SMB_PORT;
int opt;
pstring logfile;
@@ -701,7 +666,7 @@ static void usage(char *pname)
break;
case 'p':
- ports = optarg;
+ port = atoi(optarg);
break;
case 'h':
@@ -740,7 +705,7 @@ static void usage(char *pname)
lp_set_logfile(logfile);
}
- set_remote_machine_name("smbd");
+ fstrcpy(remote_machine, "smbd");
setup_logging(argv[0],interactive);
@@ -808,6 +773,11 @@ static void usage(char *pname)
init_structs();
+ /* don't call winbind for our domain if we are the DC */
+ if (lp_domain_logons()) {
+ winbind_exclude_domain(lp_workgroup());
+ }
+
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
DEBUG(0,("ERROR: failed to setup profiling\n"));
@@ -869,15 +839,13 @@ static void usage(char *pname)
start_background_queue();
*/
- if (!open_sockets_smbd(is_daemon,ports))
+ if (!open_sockets(is_daemon,port))
exit(1);
/*
* everything after this point is run after the fork()
*/
- namecache_enable();
-
if (!locking_init(0))
exit(1);
@@ -921,13 +889,6 @@ static void usage(char *pname)
if (!init_change_notify())
exit(1);
- /* re-initialise the timezone */
- TimeInit();
-
- /* register our message handlers */
- message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis);
- talloc_init_named("dummy!");
-
smbd_process();
uni_group_cache_shutdown();
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 6f83a2d3b7..9ac610ab5a 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -27,7 +27,9 @@ extern BOOL short_case_preserve;
extern BOOL case_mangle;
extern BOOL case_sensitive;
extern BOOL use_mangled_map;
+extern fstring remote_machine;
extern userdom_struct current_user_info;
+extern fstring remote_machine;
/****************************************************************************
@@ -102,9 +104,7 @@ int add_home_service(const char *service, const char *username, const char *home
}
}
- if (!lp_add_home(service, iHomeService, username, homedir)) {
- return -1;
- }
+ lp_add_home(service, iHomeService, username, homedir);
return lp_servicenumber(service);
@@ -347,7 +347,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
}
if (lp_guest_only(snum)) {
- const char *guestname = lp_guestaccount();
+ char *guestname = lp_guestaccount();
guest = True;
force = True;
pass = getpwnam_alloc(guestname);
@@ -521,7 +521,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
pstrcpy(s,lp_pathname(snum));
standard_sub_conn(conn,s,sizeof(s));
string_set(&conn->connectpath,s);
- DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum)));
+ DEBUG(3,("Connect path is %s\n",s));
}
/* groups stuff added by ih */
@@ -634,7 +634,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
I have disabled this chdir check (tridge) */
if (vfs_ChDir(conn,conn->connectpath) != 0) {
DEBUG(0,("%s (%s) Can't change directory to %s (%s)\n",
- get_remote_machine_name(), conn->client_address,
+ remote_machine, conn->client_address,
conn->connectpath,strerror(errno)));
change_to_root_user();
yield_connection(conn, lp_servicename(SNUM(conn)));
@@ -645,7 +645,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
#else
/* the alternative is just to check the directory exists */
if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
- DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn))));
+ DEBUG(0,("%s is not a directory\n", conn->connectpath));
change_to_root_user();
yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
@@ -674,7 +674,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
*/
if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
- dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address );
+ dbgtext( "%s (%s) ", remote_machine, conn->client_address );
dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
dbgtext( "initially as user %s ", user );
dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
@@ -759,7 +759,6 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
vuser = get_valid_user_struct(vuid);
if (!vuser) {
DEBUG(1,("make_connection: refusing to connect with no session setup\n"));
- *status = NT_STATUS_ACCESS_DENIED;
return NULL;
}
}
@@ -774,15 +773,12 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
if (strequal(service_in,HOMES_NAME)) {
if(lp_security() != SEC_SHARE) {
DATA_BLOB no_pw = data_blob(NULL, 0);
- if (vuser->homes_snum == -1) {
- DEBUG(2, ("[homes] share not available for this user becouse it was not found or created at session setup time\n"));
- *status = NT_STATUS_BAD_NETWORK_NAME;
- return NULL;
+ if (vuser->homes_snum != -1) {
+ DEBUG(5, ("making a connection to [homes] service created at session setup time\n"));
+ return make_connection_snum(vuser->homes_snum,
+ vuser, no_pw,
+ dev, status);
}
- DEBUG(5, ("making a connection to [homes] service created at session setup time\n"));
- return make_connection_snum(vuser->homes_snum,
- vuser, no_pw,
- dev, status);
} else {
/* Security = share. Try with current_user_info.smb_name
* as the username. */
@@ -801,7 +797,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
}
}
} else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
- && strequal(service_in, lp_servicename(vuser->homes_snum))) {
+ && strequal(service, lp_servicename(vuser->homes_snum))) {
DATA_BLOB no_pw = data_blob(NULL, 0);
DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service));
return make_connection_snum(vuser->homes_snum,
@@ -823,7 +819,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
}
DEBUG(0,("%s (%s) couldn't find service %s\n",
- get_remote_machine_name(), client_addr(), service));
+ remote_machine, client_addr(), service));
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
}
@@ -845,7 +841,7 @@ void close_cnum(connection_struct *conn, uint16 vuid)
change_to_root_user();
DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
- get_remote_machine_name(),conn->client_address,
+ remote_machine,conn->client_address,
lp_servicename(SNUM(conn))));
if (conn->vfs_ops.disconnect != NULL) {
diff --git a/source3/smbd/session.c b/source3/smbd/session.c
index 54b7a24b07..dade953ec1 100644
--- a/source3/smbd/session.c
+++ b/source3/smbd/session.c
@@ -27,22 +27,21 @@
#include "includes.h"
+extern fstring remote_machine;
+
static TDB_CONTEXT *tdb;
/* called when a session is created */
BOOL session_claim(user_struct *vuser)
{
- int i = 0;
+ int i;
TDB_DATA data;
struct sessionid sessionid;
uint32 pid = (uint32)sys_getpid();
TDB_DATA key;
fstring keystr;
char * hostname;
- int tdb_store_flag; /* If using utmp, we do an inital 'lock hold' store,
- but we don't need this if we are just using the
- (unique) pid/vuid combination */
- vuser->session_keystr = NULL;
+ vuser->session_id = 0;
/* don't register sessions for the guest user - its just too
expensive to go through pam session code for browsing etc */
@@ -64,37 +63,18 @@ BOOL session_claim(user_struct *vuser)
data.dptr = NULL;
data.dsize = 0;
-#if WITH_UTMP
- if (lp_utmp()) {
- for (i=1;i<MAX_SESSION_ID;i++) {
- slprintf(keystr, sizeof(keystr)-1, "ID/%d", i);
- key.dptr = keystr;
- key.dsize = strlen(keystr)+1;
-
- if (tdb_store(tdb, key, data, TDB_INSERT) == 0) break;
- }
-
- if (i == MAX_SESSION_ID) {
- DEBUG(1,("session_claim: out of session IDs (max is %d)\n",
- MAX_SESSION_ID));
- return False;
- }
- slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_UTMP_TEMPLATE, i);
- tdb_store_flag = TDB_MODIFY;
- } else
-#endif
- {
- slprintf(keystr, sizeof(keystr)-1, "ID/%lu/%u",
- (long unsigned int)sys_getpid(),
- vuser->vuid);
- slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1,
- SESSION_TEMPLATE, (long unsigned int)sys_getpid(),
- vuser->vuid);
-
+ for (i=1;i<MAX_SESSION_ID;i++) {
+ slprintf(keystr, sizeof(keystr)-1, "ID/%d", i);
key.dptr = keystr;
key.dsize = strlen(keystr)+1;
-
- tdb_store_flag = TDB_REPLACE;
+
+ if (tdb_store(tdb, key, data, TDB_INSERT) == 0) break;
+ }
+
+ if (i == MAX_SESSION_ID) {
+ DEBUG(1,("session_claim: out of session IDs (max is %d)\n",
+ MAX_SESSION_ID));
+ return False;
}
/* If 'hostname lookup' == yes, then do the DNS lookup. This is
@@ -110,25 +90,24 @@ BOOL session_claim(user_struct *vuser)
fstrcpy(sessionid.username, vuser->user.unix_name);
fstrcpy(sessionid.hostname, hostname);
- sessionid.id_num = i; /* Only valid for utmp sessions */
+ slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_TEMPLATE, i);
+ sessionid.id_num = i;
sessionid.pid = pid;
sessionid.uid = vuser->uid;
sessionid.gid = vuser->gid;
- fstrcpy(sessionid.remote_machine, get_remote_machine_name());
+ fstrcpy(sessionid.remote_machine, remote_machine);
fstrcpy(sessionid.ip_addr, client_addr());
if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, sessionid.hostname)) {
DEBUG(1,("pam_session rejected the session for %s [%s]\n",
sessionid.username, sessionid.id_str));
- if (tdb_store_flag == TDB_MODIFY) {
- tdb_delete(tdb, key);
- }
+ tdb_delete(tdb, key);
return False;
}
data.dptr = (char *)&sessionid;
data.dsize = sizeof(sessionid);
- if (tdb_store(tdb, key, data, tdb_store_flag) != 0) {
+ if (tdb_store(tdb, key, data, TDB_MODIFY) != 0) {
DEBUG(1,("session_claim: unable to create session id record\n"));
return False;
}
@@ -140,11 +119,7 @@ BOOL session_claim(user_struct *vuser)
}
#endif
- vuser->session_keystr = strdup(keystr);
- if (!vuser->session_keystr) {
- DEBUG(0, ("session_claim: strdup() failed for session_keystr\n"));
- return False;
- }
+ vuser->session_id = i;
return True;
}
@@ -154,15 +129,18 @@ void session_yield(user_struct *vuser)
TDB_DATA dbuf;
struct sessionid sessionid;
TDB_DATA key;
+ fstring keystr;
if (!tdb) return;
- if (!vuser->session_keystr) {
+ if (vuser->session_id == 0) {
return;
}
- key.dptr = vuser->session_keystr;
- key.dsize = strlen(vuser->session_keystr)+1;
+ slprintf(keystr, sizeof(keystr)-1, "ID/%d", vuser->session_id);
+
+ key.dptr = keystr;
+ key.dsize = strlen(keystr)+1;
dbuf = tdb_fetch(tdb, key);
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 8fb5a50697..867b00ff5c 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -3,7 +3,6 @@
handle SMBsessionsetup
Copyright (C) Andrew Tridgell 1998-2001
Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jim McDonough 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -123,12 +122,6 @@ static int reply_spnego_kerberos(connection_struct *conn,
ads = ads_init_simple();
- if (!ads) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- ads->auth.realm = strdup(lp_realm());
-
ret = ads_verify_ticket(ads, &ticket, &client, &auth_data);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1,("Failed to verify incoming ticket!\n"));
@@ -146,7 +139,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
}
*p = 0;
- if (strcasecmp(p+1, ads->auth.realm) != 0) {
+ if (strcasecmp(p+1, ads->realm) != 0) {
DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
if (!lp_allow_trusted_domains()) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
@@ -207,7 +200,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
send a security blob via a session setup reply
****************************************************************************/
static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
- DATA_BLOB blob, uint32 errcode)
+ DATA_BLOB blob)
{
char *p;
@@ -216,7 +209,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
/* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end
that we aren't finished yet */
- SIVAL(outbuf, smb_rcls, errcode);
+ SIVAL(outbuf, smb_rcls, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
SSVAL(outbuf, smb_vwv3, blob.length);
p = smb_buf(outbuf);
@@ -243,12 +236,11 @@ static int reply_spnego_negotiate(connection_struct *conn,
DATA_BLOB secblob;
int i;
uint32 ntlmssp_command, neg_flags, chal_flags;
- DATA_BLOB chal, spnego_chal;
+ DATA_BLOB chal, spnego_chal, extra_data;
const uint8 *cryptkey;
BOOL got_kerberos = False;
NTSTATUS nt_status;
extern pstring global_myname;
- char *cliname=NULL, *domname=NULL;
/* parse out the OIDs and the first sec blob */
if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
@@ -266,7 +258,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
DEBUG(3,("Got secblob of size %d\n", secblob.length));
#ifdef HAVE_KRB5
- if (got_kerberos && (SEC_ADS == lp_security())) {
+ if (got_kerberos) {
int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
length, bufsize, &secblob);
data_blob_free(&secblob);
@@ -279,16 +271,19 @@ static int reply_spnego_negotiate(connection_struct *conn,
file_save("secblob.dat", secblob.data, secblob.length);
#endif
- if (!msrpc_parse(&secblob, "CddAA",
+ if (!msrpc_parse(&secblob, "CddB",
"NTLMSSP",
&ntlmssp_command,
&neg_flags,
- &cliname,
- &domname)) {
+ &extra_data)) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
+ DEBUG(5, ("Extra data: \n"));
+ dump_data(5, extra_data.data, extra_data.length);
+
data_blob_free(&secblob);
+ data_blob_free(&extra_data);
if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
@@ -317,39 +312,36 @@ static int reply_spnego_negotiate(connection_struct *conn,
NTLMSSP_CHAL_TARGET_INFO;
{
- DATA_BLOB domain_blob, struct_blob;
- fstring dnsname, dnsdomname;
+ DATA_BLOB domain_blob, netbios_blob, realm_blob;
msrpc_gen(&domain_blob,
"U",
lp_workgroup());
- fstrcpy(dnsdomname, lp_realm());
- strlower(dnsdomname);
-
- fstrcpy(dnsname, global_myname);
- fstrcat(dnsname, ".");
- fstrcat(dnsname, lp_realm());
- strlower(dnsname);
-
- msrpc_gen(&struct_blob, "aaaaa",
- 2, lp_workgroup(),
- 1, global_myname,
- 4, dnsdomname,
- 3, dnsname,
- 0, "");
+ msrpc_gen(&netbios_blob,
+ "U",
+ global_myname);
+
+ msrpc_gen(&realm_blob,
+ "U",
+ lp_realm());
+
- msrpc_gen(&chal, "CdUdbddB",
+ msrpc_gen(&chal, "CddddbBBBB",
"NTLMSSP",
NTLMSSP_CHALLENGE,
- lp_workgroup(),
+ 0,
+ 0x30, /* ?? */
chal_flags,
cryptkey, 8,
- 0, 0,
- struct_blob.data, struct_blob.length);
+ domain_blob.data, domain_blob.length,
+ domain_blob.data, domain_blob.length,
+ netbios_blob.data, netbios_blob.length,
+ realm_blob.data, realm_blob.length);
data_blob_free(&domain_blob);
- data_blob_free(&struct_blob);
+ data_blob_free(&netbios_blob);
+ data_blob_free(&realm_blob);
}
if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) {
@@ -359,7 +351,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
}
/* now tell the client to send the auth packet */
- reply_sesssetup_blob(conn, outbuf, spnego_chal, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
+ reply_sesssetup_blob(conn, outbuf, spnego_chal);
data_blob_free(&chal);
data_blob_free(&spnego_chal);
@@ -376,7 +368,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
int length, int bufsize,
DATA_BLOB blob1)
{
- DATA_BLOB auth, response;
+ DATA_BLOB auth;
char *workgroup = NULL, *user = NULL, *machine = NULL;
DATA_BLOB lmhash, nthash, sess_key;
DATA_BLOB plaintext_password = data_blob(NULL, 0);
@@ -421,13 +413,6 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n",
user, workgroup, machine, lmhash.length, nthash.length));
- /* the client has given us its machine name (which we otherwise would not get on port 445).
- we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
-
- set_remote_machine_name(machine);
-
- reload_services(True);
-
#if 0
file_save("nthash1.dat", nthash.data, nthash.length);
file_save("lmhash1.dat", lmhash.data, lmhash.length);
@@ -496,12 +481,8 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
-
- response = spnego_gen_auth_response();
- reply_sesssetup_blob(conn, outbuf, response, 0);
-
- /* and tell smbd that we have already replied to this packet */
- return -1;
+
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -613,6 +594,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
extern BOOL global_encrypted_passwords_negotiated;
extern BOOL global_spnego_negotiated;
extern int Protocol;
+ extern fstring remote_machine;
extern userdom_struct current_user_info;
extern int max_send;
@@ -648,8 +630,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
if (Protocol < PROTOCOL_NT1) {
uint16 passlen1 = SVAL(inbuf,smb_vwv7);
- if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ if (passlen1 > MAX_PASS_LEN) {
+ return ERROR_DOS(ERRDOS,ERRbuftoosmall);
}
if (doencrypt) {
@@ -683,6 +665,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
}
}
+ if (passlen1 > MAX_PASS_LEN) {
+ return ERROR_DOS(ERRDOS,ERRbuftoosmall);
+ }
+
+ passlen1 = MIN(passlen1, MAX_PASS_LEN);
+ passlen2 = MIN(passlen2, MAX_PASS_LEN);
+
if (!doencrypt) {
/* both Win95 and WinNT stuff up the password lengths for
non-encrypting systems. Uggh.
@@ -700,29 +689,19 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
passlen2 = 0;
}
- /* check for nasty tricks */
- if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
- if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
/* Save the lanman2 password and the NT md4 password. */
if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
doencrypt = False;
}
-
+
if (doencrypt) {
lm_resp = data_blob(p, passlen1);
nt_resp = data_blob(p+passlen1, passlen2);
} else {
- pstring pass;
- srvstr_pull(inbuf, pass, smb_buf(inbuf),
- sizeof(pass), passlen1, STR_TERMINATE);
- plaintext_password = data_blob(pass, strlen(pass)+1);
+ plaintext_password = data_blob(p, passlen1+1);
+ /* Ensure null termination */
+ plaintext_password.data[passlen1] = 0;
}
p += passlen1 + passlen2;
@@ -741,7 +720,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
- DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name()));
+ DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
if (*user) {
if (global_spnego_negotiated) {
diff --git a/source3/smbd/ssl.c b/source3/smbd/ssl.c
new file mode 100644
index 0000000000..7fcb48a954
--- /dev/null
+++ b/source3/smbd/ssl.c
@@ -0,0 +1,286 @@
+/*
+ Unix SMB/CIFS implementation.
+ SSLeay utility functions
+ Copyright (C) Christian Starkjohann <cs@obdev.at> 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * since includes.h pulls in config.h which is were WITH_SSL will be
+ * defined, we want to include includes.h before testing for WITH_SSL
+ * RJS 26-Jan-1999
+ */
+
+#include "includes.h"
+
+#ifdef WITH_SSL /* should always be defined if this module is compiled */
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+BOOL sslEnabled;
+SSL *ssl = NULL;
+int sslFd = -1;
+static SSL_CTX *sslContext = NULL;
+extern int DEBUGLEVEL;
+
+static int ssl_verify_cb(int ok, X509_STORE_CTX *ctx)
+{
+char buffer[256];
+
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),
+ buffer, sizeof(buffer));
+ if(ok){
+ DEBUG(0, ("SSL: Certificate OK: %s\n", buffer));
+ }else{
+ switch (ctx->error){
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ DEBUG(0, ("SSL: Cert error: CA not known: %s\n", buffer));
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ DEBUG(0, ("SSL: Cert error: Cert not yet valid: %s\n", buffer));
+ break;
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ DEBUG(0, ("SSL: Cert error: illegal \'not before\' field: %s\n",
+ buffer));
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ DEBUG(0, ("SSL: Cert error: Cert expired: %s\n", buffer));
+ break;
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ DEBUG(0, ("SSL: Cert error: invalid \'not after\' field: %s\n",
+ buffer));
+ break;
+ default:
+ DEBUG(0, ("SSL: Cert error: unknown error %d in %s\n", ctx->error,
+ buffer));
+ break;
+ }
+ }
+ return ok;
+}
+
+static RSA *ssl_temp_rsa_cb(SSL *ssl, int is_export, int keylength)
+{
+static RSA *rsa = NULL;
+
+ if(rsa == NULL)
+ rsa = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
+ return rsa;
+}
+
+/* This is called before we fork. It should ask the user for the pass phrase
+ * if necessary. Error output can still go to stderr because the process
+ * has a terminal.
+ */
+int sslutil_init(int isServer)
+{
+int err, entropybytes;
+char *certfile, *keyfile, *ciphers, *cacertDir, *cacertFile;
+char *egdsocket, *entropyfile;
+
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
+ egdsocket = lp_ssl_egdsocket();
+ if (egdsocket != NULL && *egdsocket != 0)
+ RAND_egd(egdsocket);
+ entropyfile = lp_ssl_entropyfile();
+ entropybytes = lp_ssl_entropybytes();
+ if (entropyfile != NULL && *entropyfile != 0)
+ RAND_load_file(entropyfile, entropybytes);
+ switch(lp_ssl_version()){
+ case SMB_SSL_V2: sslContext = SSL_CTX_new(SSLv2_method()); break;
+ case SMB_SSL_V3: sslContext = SSL_CTX_new(SSLv3_method()); break;
+ default:
+ case SMB_SSL_V23: sslContext = SSL_CTX_new(SSLv23_method()); break;
+ case SMB_SSL_TLS1: sslContext = SSL_CTX_new(TLSv1_method()); break;
+ }
+ if(sslContext == NULL){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: Error allocating context: %s\n",
+ ERR_error_string(err, NULL));
+ exit(1);
+ }
+ if(lp_ssl_compatibility()){
+ SSL_CTX_set_options(sslContext, SSL_OP_ALL);
+ }
+ certfile = isServer ? lp_ssl_server_cert() : lp_ssl_client_cert();
+ if((certfile == NULL || *certfile == 0) && isServer){
+ fprintf(stderr, "SSL: No cert file specified in config file!\n");
+ fprintf(stderr, "The server MUST have a certificate!\n");
+ exit(1);
+ }
+ keyfile = isServer ? lp_ssl_server_privkey() : lp_ssl_client_privkey();
+ if(keyfile == NULL || *keyfile == 0)
+ keyfile = certfile;
+ if(certfile != NULL && *certfile != 0){
+ if(!SSL_CTX_use_certificate_chain_file(sslContext, certfile)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: error reading certificate from file %s: %s\n",
+ certfile, ERR_error_string(err, NULL));
+ exit(1);
+ }
+ if(!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: error reading private key from file %s: %s\n",
+ keyfile, ERR_error_string(err, NULL));
+ exit(1);
+ }
+ if(!SSL_CTX_check_private_key(sslContext)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: Private key does not match public key in cert!\n");
+ exit(1);
+ }
+ }
+ cacertDir = lp_ssl_cacertdir();
+ cacertFile = lp_ssl_cacertfile();
+ if(cacertDir != NULL && *cacertDir == 0)
+ cacertDir = NULL;
+ if(cacertFile != NULL && *cacertFile == 0)
+ cacertFile = NULL;
+ if(!SSL_CTX_load_verify_locations(sslContext, cacertFile, cacertDir)){
+ err = ERR_get_error();
+ if (cacertFile || cacertDir) {
+ fprintf(stderr, "SSL: Error error setting CA cert locations: %s\n",
+ ERR_error_string(err, NULL));
+ fprintf(stderr, "trying default locations.\n");
+ }
+ cacertFile = cacertDir = NULL;
+ if(!SSL_CTX_set_default_verify_paths(sslContext)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: Error error setting default CA cert location: %s\n",
+ ERR_error_string(err, NULL));
+ exit(1);
+ }
+ }
+ SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
+ if((ciphers = lp_ssl_ciphers()) != NULL && *ciphers != 0)
+ SSL_CTX_set_cipher_list(sslContext, ciphers);
+ if((isServer && lp_ssl_reqClientCert()) || (!isServer && lp_ssl_reqServerCert())){
+ SSL_CTX_set_verify(sslContext,
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
+ }else{
+ SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, ssl_verify_cb);
+ }
+#if 1 /* don't know what this is good for, but s_server in SSLeay does it, too */
+ if(isServer){
+ SSL_CTX_set_client_CA_list(sslContext, SSL_load_client_CA_file(certfile));
+ }
+#endif
+ return 0;
+}
+
+int sslutil_accept(int fd)
+{
+int err;
+
+ if(ssl != NULL){
+ DEBUG(0, ("SSL: internal error: more than one SSL connection (server)\n"));
+ return -1;
+ }
+ if((ssl = SSL_new(sslContext)) == NULL){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error allocating handle: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ SSL_set_fd(ssl, fd);
+ sslFd = fd;
+ if(SSL_accept(ssl) <= 0){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error accepting on socket: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ DEBUG(0, ("SSL: negotiated cipher: %s\n", SSL_get_cipher(ssl)));
+ return 0;
+}
+
+int sslutil_fd_is_ssl(int fd)
+{
+ return fd == sslFd;
+}
+
+int sslutil_connect(int fd)
+{
+int err;
+
+ if(ssl != NULL){
+ DEBUG(0, ("SSL: internal error: more than one SSL connection (client)\n"));
+ return -1;
+ }
+ if((ssl = SSL_new(sslContext)) == NULL){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error allocating handle: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ SSL_set_fd(ssl, fd);
+ sslFd = fd;
+ if(SSL_connect(ssl) <= 0){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error conencting socket: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ DEBUG(0, ("SSL: negotiated cipher: %s\n", SSL_get_cipher(ssl)));
+ return 0;
+}
+
+int sslutil_disconnect(int fd)
+{
+ if(fd == sslFd && ssl != NULL){
+ SSL_free(ssl);
+ ssl = NULL;
+ sslFd = -1;
+ }
+ return 0;
+}
+
+int sslutil_negotiate_ssl(int fd, int msg_type)
+{
+unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
+char *reqHosts, *resignHosts;
+
+ reqHosts = lp_ssl_hosts();
+ resignHosts = lp_ssl_hosts_resign();
+ if(!allow_access(resignHosts, reqHosts, get_socket_name(fd), get_socket_addr(fd))){
+ sslEnabled = False;
+ return 0;
+ }
+ if(msg_type != 0x81){ /* first packet must be a session request */
+ DEBUG( 0, ( "Client %s did not use session setup; access denied\n",
+ client_addr() ) );
+ if (!send_smb(fd, (char *)buf))
+ DEBUG(0, ("sslutil_negotiate_ssl: send_smb failed.\n"));
+ return -1;
+ }
+ buf[4] = 0x8e; /* negative session response: use SSL */
+ if (!send_smb(fd, (char *)buf)) {
+ DEBUG(0,("sslutil_negotiate_ssl: send_smb failed.\n"));
+ return -1;
+ }
+ if(sslutil_accept(fd) != 0){
+ DEBUG( 0, ( "Client %s failed SSL negotiation!\n", client_addr() ) );
+ return -1;
+ }
+ return 1;
+}
+
+#else /* WITH_SSL */
+ void ssl_dummy(void);
+ void ssl_dummy(void) {;} /* So some compilers don't complain. */
+#endif /* WITH_SSL */
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index a66c029286..f1dfb39aac 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -30,19 +30,6 @@ extern int global_oplock_break;
extern uint32 global_client_caps;
extern pstring global_myname;
-/* given a stat buffer return the allocated size on disk, taking into
- account sparse files */
-SMB_OFF_T get_allocation_size(SMB_STRUCT_STAT *sbuf)
-{
- SMB_OFF_T ret;
- ret = sbuf->st_blksize * (SMB_OFF_T)sbuf->st_blocks;
- ret = SMB_ROUNDUP_ALLOCATION(ret);
- return ret;
-}
-
-#define get_file_size(sbuf) (sbuf.st_size)
-
-
/****************************************************************************
Send the required number of replies back.
We assume all fields other than the data fields are
@@ -269,7 +256,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- size = get_file_size(sbuf);
+ size = sbuf.st_size;
fmode = dos_mode(conn,fname,&sbuf);
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
@@ -466,7 +453,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
uint32 reskey=0;
int prev_dirpos=0;
int mode=0;
- SMB_OFF_T file_size = 0;
+ SMB_OFF_T size = 0;
SMB_OFF_T allocation_size = 0;
uint32 len;
time_t mdate=0, adate=0, cdate=0;
@@ -578,8 +565,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
continue;
}
- file_size = get_file_size(sbuf);
- allocation_size = get_allocation_size(&sbuf);
+ size = sbuf.st_size;
+ allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
mdate = sbuf.st_mtime;
adate = sbuf.st_atime;
cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
@@ -591,7 +578,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
}
if(mode & aDIR)
- file_size = 0;
+ size = 0;
DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
@@ -615,7 +602,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l1_fdateCreation,cdate);
put_dos_date2(p,l1_fdateLastAccess,adate);
put_dos_date2(p,l1_fdateLastWrite,mdate);
- SIVAL(p,l1_cbFile,(uint32)file_size);
+ SIVAL(p,l1_cbFile,(uint32)size);
SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l1_attrFile,mode);
p += l1_achName;
@@ -634,7 +621,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l2_fdateCreation,cdate);
put_dos_date2(p,l2_fdateLastAccess,adate);
put_dos_date2(p,l2_fdateLastWrite,mdate);
- SIVAL(p,l2_cbFile,(uint32)file_size);
+ SIVAL(p,l2_cbFile,(uint32)size);
SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l2_attrFile,mode);
SIVAL(p,l2_cbList,0); /* No extended attributes */
@@ -654,7 +641,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,adate); p += 8;
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size);
+ SOFF_T(p,0,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@@ -688,7 +675,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,adate); p += 8;
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size);
+ SOFF_T(p,0,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@@ -709,7 +696,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,adate); p += 8;
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size);
+ SOFF_T(p,0,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@@ -748,14 +735,14 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
/* Begin of SMB_QUERY_FILE_UNIX_BASIC */
- SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
+ SOFF_T(p,0,sbuf.st_size); /* File size 64 Bit */
p+= 8;
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
#else
/* Can't get the value - fake it using size. */
- SOFF_T(p,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
+ SOFF_T(p,0,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
#endif
p+= 8;
@@ -1541,7 +1528,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint16 tran_call = SVAL(inbuf, smb_setup0);
uint16 info_level;
int mode=0;
- SMB_OFF_T file_size=0;
+ SMB_OFF_T size=0;
SMB_OFF_T allocation_size=0;
unsigned int data_size;
SMB_STRUCT_STAT sbuf;
@@ -1656,10 +1643,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
mode = dos_mode(conn,fname,&sbuf);
fullpathname = fname;
- file_size = get_file_size(sbuf);
- allocation_size = get_allocation_size(&sbuf);
+ size = sbuf.st_size;
+ allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
if (mode & aDIR)
- file_size = 0;
+ size = 0;
params = Realloc(*pparams,2);
if (params == NULL)
@@ -1705,7 +1692,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,l1_fdateCreation,c_time);
put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
- SIVAL(pdata,l1_cbFile,(uint32)file_size);
+ SIVAL(pdata,l1_cbFile,(uint32)size);
SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode);
SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
@@ -1716,7 +1703,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,0,c_time);
put_dos_date2(pdata,4,sbuf.st_atime);
put_dos_date2(pdata,8,sbuf.st_mtime);
- SIVAL(pdata,12,(uint32)file_size);
+ SIVAL(pdata,12,(uint32)size);
SIVAL(pdata,16,(uint32)allocation_size);
SIVAL(pdata,20,mode);
break;
@@ -1760,8 +1747,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_QUERY_FILE_STANDARD_INFO:
data_size = 24;
+ /* Fake up allocation size. */
SOFF_T(pdata,0,allocation_size);
- SOFF_T(pdata,8,file_size);
+ SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,0);
SCVAL(pdata,21,(mode&aDIR)?1:0);
@@ -1806,7 +1794,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_QUERY_FILE_END_OF_FILEINFO:
data_size = 8;
- SOFF_T(pdata,0,file_size);
+ SOFF_T(pdata,0,size);
break;
case SMB_QUERY_FILE_ALL_INFO:
@@ -1817,7 +1805,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,32,mode);
pdata += 40;
SOFF_T(pdata,0,allocation_size);
- SOFF_T(pdata,8,file_size);
+ SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,delete_pending);
SCVAL(pdata,21,(mode&aDIR)?1:0);
@@ -1929,7 +1917,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
SIVAL(pdata,0,0); /* ??? */
SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
- SOFF_T(pdata,8,file_size);
+ SOFF_T(pdata,8,size);
SIVAL(pdata,16,allocation_size);
SIVAL(pdata,20,0); /* ??? */
data_size = 24 + byte_len;
@@ -1937,7 +1925,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
case SMB_FILE_COMPRESSION_INFORMATION:
- SOFF_T(pdata,0,allocation_size);
+ SOFF_T(pdata,0,size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
data_size = 16;
@@ -1949,7 +1937,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_long_date(pdata+16,sbuf.st_mtime); /* write time */
put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,allocation_size);
- SOFF_T(pdata,40,file_size);
+ SOFF_T(pdata,40,size);
SIVAL(pdata,48,mode);
SIVAL(pdata,52,0); /* ??? */
data_size = 56;
@@ -1969,14 +1957,14 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
- SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
+ SOFF_T(pdata,0,sbuf.st_size); /* File size 64 Bit */
pdata += 8;
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
SOFF_T(pdata,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
#else
/* Can't get the value - fake it using size. */
- SOFF_T(pdata,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
+ SOFF_T(pdata,0,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
#endif
pdata += 8;
@@ -2258,8 +2246,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
- } else
- return (UNIXERROR(ERRDOS,ERRbadpath));
+ }
} else {
/*
* Original code - this is an open file.
@@ -2323,7 +2310,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
sbuf.st_mtime = fsp->pending_modtime;
}
- size = get_file_size(sbuf);
+ size = sbuf.st_size;
tvs.modtime = sbuf.st_mtime;
tvs.actime = sbuf.st_atime;
dosmode = dos_mode(conn,fname,&sbuf);
@@ -2426,7 +2413,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
fname, (double)allocation_size ));
- if(allocation_size != get_file_size(sbuf)) {
+ if(allocation_size != sbuf.st_size) {
SMB_STRUCT_STAT new_sbuf;
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
@@ -2472,8 +2459,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (ret == -1)
return ERROR_NT(NT_STATUS_DISK_FULL);
- /* Allocate can truncate size... */
- size = get_file_size(new_sbuf);
+ /* Allocate can trucate size... */
+ size = new_sbuf.st_size;
}
break;
@@ -2728,7 +2715,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* changing the size of a file.
*/
if (!size)
- size = get_file_size(sbuf);
+ size = sbuf.st_size;
}
/*
@@ -2770,7 +2757,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
}
- if (size != get_file_size(sbuf)) {
+ if(size != sbuf.st_size) {
int ret;
@@ -2983,11 +2970,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
{
char *pdata = *ppdata;
files_struct *fsp = file_fsp(inbuf,smb_vwv15);
-
+
if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
- uint16 rap_jobid;
-
pdata = Realloc(*ppdata, 32);
if(pdata == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
@@ -2996,8 +2981,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
/* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
CAN ACCEPT THIS IN UNICODE. JRA. */
- rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); /* Job number */
- SSVAL(pdata,0,rap_jobid); /* Job number */
+ SSVAL(pdata,0,fsp->print_jobid); /* Job number */
srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index c0bacf8f91..a18f62c9cc 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -440,43 +440,44 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N
extern pstring global_myname;
extern fstring global_myworkgroup;
fstring sid;
- BOOL local_lookup = False;
+ BOOL ret = False;
*name_type = SID_NAME_UNKNOWN;
/* If we are looking up a domain user, make sure it is
for the local machine only */
- if (strequal(global_myname, domain)) {
- local_lookup = True;
- } else if (lp_server_role() == ROLE_DOMAIN_PDC ||
- lp_server_role() == ROLE_DOMAIN_PDC) {
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
if (strequal(domain, global_myworkgroup)) {
- local_lookup = True;
+ ret = local_lookup_name(name, psid, name_type);
}
- }
-
- if (local_lookup) {
- if (local_lookup_name(name, psid, name_type)) {
- DEBUG(10,
- ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
- domain, name, sid_to_string(sid,psid),
- sid_type_lookup(*name_type), (unsigned int)*name_type));
- return True;
- }
- } else {
- /* Remote */
- if (winbind_lookup_name(domain, name, psid, name_type)) {
-
- DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
- domain, name, sid_to_string(sid, psid),
- (unsigned int)*name_type));
- return True;
+ /* No break is deliberate here. JRA. */
+ default:
+ if (ret) {
+ } else if (strequal(global_myname, domain)) {
+ ret = local_lookup_name(name, psid, name_type);
+ } else {
+ DEBUG(5, ("lookup_name: domain %s is not local\n", domain));
}
}
- DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
- local_lookup ? "local" : "winbind", domain, name));
+ if (ret) {
+ DEBUG(10,
+ ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
+ domain, name, sid_to_string(sid,psid),
+ sid_type_lookup(*name_type), (unsigned int)*name_type));
+ return True;
+ } else if (winbind_lookup_name(domain, name, psid, name_type)) {
+
+ DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
+ domain, name, sid_to_string(sid, psid),
+ (unsigned int)*name_type));
+ return True;
+ }
+
+ DEBUG(10, ("lookup_name: winbind and local lookups for [%s]\\[%s] failed\n", domain, name));
return False;
}
@@ -592,17 +593,13 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
was done correctly, False if not. sidtype is set by this function.
*****************************************************************/
-BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
+BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
{
fstring sid_str;
/* if we know its local then don't try winbindd */
if (sid_compare_domain(get_global_sam_sid(), psid) == 0) {
- BOOL result;
- become_root();
- result = local_sid_to_uid(puid, psid, sidtype);
- unbecome_root();
- return result;
+ return local_sid_to_uid(puid, psid, sidtype);
}
/* (tridge) I commented out the slab of code below in order to support foreign SIDs
@@ -668,7 +665,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
was done correctly, False if not.
*****************************************************************/
-BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
+BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
{
fstring dom_name, name, sid_str;
enum SID_NAME_USE name_type;
@@ -679,21 +676,16 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
* First we must look up the name and decide if this is a group sid.
*/
- /* if we know its local then don't try winbindd */
- if (sid_compare_domain(get_global_sam_sid(), psid) == 0) {
- BOOL result;
- become_root();
- result = local_sid_to_gid(pgid, psid, sidtype);
- unbecome_root();
- return result;
- }
-
if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
- DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
+ DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
sid_to_string(sid_str, psid) ));
- /* this was probably a foreign sid - assume its a group rid
- and continue */
- name_type = SID_NAME_DOM_GRP;
+ if (!local_sid_to_gid(pgid, psid, sidtype)) {
+ /* this was probably a foreign sid - assume its a group rid
+ and continue */
+ name_type = SID_NAME_DOM_GRP;
+ } else {
+ return True;
+ }
}
/*
@@ -704,7 +696,7 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
(unsigned int)name_type ));
- return False;
+ return local_sid_to_gid(pgid, psid, sidtype);
}
*sidtype = name_type;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index a2291eba08..5e1dc68bdb 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -3,7 +3,6 @@
Version 1.9.
VFS initialisation and support functions
Copyright (C) Tim Potter 1999
- Copyright (C) Alexander Bokovoy 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,8 +17,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- This work was sponsored by Optifacio Software Services, Inc.
*/
#include "includes.h"
@@ -31,12 +28,6 @@ struct vfs_syminfo {
void *fptr;
};
-/*
- Opaque (final) vfs operations. This is a combination of first-met opaque vfs operations
- across all currently processed modules. */
-
-static vfs_op_tuple vfs_opaque_ops[SMB_VFS_OP_LAST];
-
/* Default vfs hooks. WARNING: The order of these initialisers is
very important. They must be in the same order as defined in
vfs.h. Change at your own peril. */
@@ -126,75 +117,58 @@ static struct vfs_ops default_vfs_ops = {
initialise default vfs hooks
****************************************************************************/
-static void vfs_init_default(connection_struct *conn)
+static BOOL vfs_init_default(connection_struct *conn)
{
DEBUG(3, ("Initialising default vfs hooks\n"));
memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(struct vfs_ops));
- conn->vfs_private = NULL;
+ return True;
}
/****************************************************************************
initialise custom vfs hooks
****************************************************************************/
-static BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
+static BOOL vfs_init_custom(connection_struct *conn)
{
int vfs_version = -1;
- vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *);
- int i;
+ struct vfs_ops *ops, *(*init_fptr)(int *, struct vfs_ops *);
- DEBUG(3, ("Initialising custom vfs hooks from %s\n", vfs_object));
+ DEBUG(3, ("Initialising custom vfs hooks from %s\n", lp_vfsobj(SNUM(conn))));
/* Open object file */
- if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) {
- DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror()));
+ if ((conn->dl_handle = sys_dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW | RTLD_GLOBAL)) == NULL) {
+ DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)), sys_dlerror()));
return False;
}
/* Get handle on vfs_init() symbol */
- init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init");
+ init_fptr = (struct vfs_ops *(*)(int *, struct vfs_ops *))sys_dlsym(conn->dl_handle, "vfs_init");
if (init_fptr == NULL) {
- DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object));
+ DEBUG(0, ("No vfs_init() symbol found in %s\n", lp_vfsobj(SNUM(conn))));
return False;
}
/* Initialise vfs_ops structure */
- if ((ops = init_fptr(&vfs_version, &conn->vfs_ops, conn->vfs_private)) == NULL) {
- DEBUG(0, ("vfs_init() function from %s failed\n", vfs_object));
- return False;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_CASCADED)) {
- DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION ));
- return False;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_VERSION)) {
- DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\
-Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION, vfs_version ));
- return False;
- }
-
- for(i=0; ops[i].op != NULL; i++) {
- DEBUG(3, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));
- if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) {
- /* Check whether this operation was already made opaque by different module */
- if(vfs_opaque_ops[ops[i].type].op == ((void**)&default_vfs_ops)[ops[i].type]) {
- /* No, it isn't overloaded yet. Overload. */
- DEBUG(3, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
- vfs_opaque_ops[ops[i].type] = ops[i];
- }
- }
- /* Change current VFS disposition*/
- DEBUG(3, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object));
- ((void**)&conn->vfs_ops)[ops[i].type] = ops[i].op;
+ conn->vfs_ops = default_vfs_ops;
+
+ if ((ops = init_fptr(&vfs_version, &default_vfs_ops)) == NULL) {
+ DEBUG(0, ("vfs_init function from %s failed\n", lp_vfsobj(SNUM(conn))));
+ return False;
+ }
+
+ if (vfs_version != SMB_VFS_INTERFACE_VERSION) {
+ DEBUG(0, ("vfs_init returned wrong interface version info (was %d, should be %d)\n",
+ vfs_version, SMB_VFS_INTERFACE_VERSION ));
+ return False;
+ }
+
+ if (ops != &conn->vfs_ops) {
+ memcpy(&conn->vfs_ops, ops, sizeof(struct vfs_ops));
}
return True;
@@ -206,70 +180,21 @@ Proceeding in compatibility mode, new operations (since version #%d) will fallba
BOOL smbd_vfs_init(connection_struct *conn)
{
- char **vfs_objects, *vfsobj, *vfs_module, *vfs_path;
- int nobj, i;
- struct smb_vfs_handle_struct *handle;
-
- /* Normal share - initialise with disk access functions */
- vfs_init_default(conn);
-
- /* Override VFS functions if 'vfs object' was specified*/
if (*lp_vfsobj(SNUM(conn))) {
- vfsobj = NULL;
- for(i=0; i<SMB_VFS_OP_LAST; i++) {
- vfs_opaque_ops[i].op = ((void**)&default_vfs_ops)[i];
- vfs_opaque_ops[i].type = i;
- vfs_opaque_ops[i].layer = SMB_VFS_LAYER_OPAQUE;
+
+ /* Loadable object file */
+
+ if (!vfs_init_custom(conn)) {
+ DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed\n"));
+ return False;
}
- if (string_set(&vfsobj, lp_vfsobj(SNUM(conn)))) {
- /* Parse passed modules specification to array of modules */
- set_first_token(vfsobj);
- /* We are using default separators: ' \t\r\n' */
- vfs_objects = toktocliplist(&nobj, NULL);
- if (vfs_objects) {
- vfs_path = lp_vfs_path(SNUM(conn));
- conn->vfs_private = NULL;
- for(i=nobj-1; i>=0; i--) {
- handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct));
- /* Loadable object file */
- handle->handle = NULL;
- DLIST_ADD(conn->vfs_private, handle)
- vfs_module = NULL;
- if (vfs_path) {
- asprintf(&vfs_module, "%s/%s", vfs_path, vfs_objects[i]);
- } else {
- asprintf(&vfs_module, "%s", vfs_objects[i]);
- }
- if (!vfs_init_custom(conn, vfs_module)) {
- DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_module));
- string_free(&vfsobj);
- SAFE_FREE(vfs_module);
- return False;
- }
- SAFE_FREE(vfs_module);
- }
- }
- string_free(&vfsobj);
- return True;
- }
- }
- return True;
-}
-
-/*******************************************************************
- Create vfs_ops reflecting current vfs_opaque_ops
-*******************************************************************/
-struct vfs_ops *smb_vfs_get_opaque_ops(void)
-{
- int i;
- struct vfs_ops *ops;
- ops = smb_xmalloc(sizeof(struct vfs_ops));
-
- for(i=0; i<SMB_VFS_OP_LAST; i++) {
- ((void**)ops)[i] = vfs_opaque_ops[i].op;
- }
- return ops;
+ return True;
+ }
+
+ /* Normal share - initialise with disk access functions */
+
+ return vfs_init_default(conn);
}
/*******************************************************************