1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-26 18:50:30 +03:00

Sync 3.0 branch with head

(This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e)
This commit is contained in:
Jelmer Vernooij 2002-08-17 15:27:10 +00:00
parent 287d49bb5d
commit 127e77e6e3
23 changed files with 1150 additions and 847 deletions

View File

@ -282,9 +282,10 @@ 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 ((errno != EACCES) && (errno != EAGAIN)) {
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" POSIX
* We have other than a "can't get lock"
* error. Send an error.
* Return True so we get dequeued.
*/
@ -348,9 +349,10 @@ 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((errno != EACCES) && (errno != EAGAIN)) {
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" POSIX
* We have other than a "can't get lock"
* error. Send an error.
* Return True so we get dequeued.
*/
@ -432,12 +434,13 @@ static BOOL process_lockingX(blocking_lock_record *blr)
reply_lockingX_success(blr);
return True;
} 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.
*/
} 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.
*/
blocking_lock_reply_error(blr, status);
return True;

View File

@ -167,17 +167,17 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
/* Make slave stdin/out/err of child. */
if (dup2(slave, STDIN_FILENO) != STDIN_FILENO)
if (sys_dup2(slave, STDIN_FILENO) != STDIN_FILENO)
{
DEBUG(3, ("Could not re-direct stdin\n"));
return (False);
}
if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
if (sys_dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
{
DEBUG(3, ("Could not re-direct stdout\n"));
return (False);
}
if (dup2(slave, STDERR_FILENO) != STDERR_FILENO)
if (sys_dup2(slave, STDERR_FILENO) != STDERR_FILENO)
{
DEBUG(3, ("Could not re-direct stderr\n"));
return (False);
@ -196,7 +196,9 @@ 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"));

View File

@ -2,6 +2,7 @@
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
@ -162,11 +163,25 @@ 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 */
if (conn->dl_handle != NULL) {
/* Close dlopen() handle */
sys_dlclose(conn->dl_handle);
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;
}
DLIST_REMOVE(Connections, conn);

View File

@ -20,7 +20,6 @@
#include "includes.h"
extern fstring remote_machine;
static TDB_CONTEXT *tdb;
/****************************************************************************
@ -29,6 +28,11 @@ 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;
}
@ -173,7 +177,7 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
}
crec.start = time(NULL);
StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
StrnCpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)-1);
StrnCpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1);
dbuf.dptr = (char *)&crec;

View File

@ -721,6 +721,62 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
&access_granted, &status);
}
/*******************************************************************
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.
********************************************************************/
@ -781,6 +837,19 @@ 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;

View File

@ -115,65 +115,67 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
/****************************************************************************
change a unix mode to a dos mode
****************************************************************************/
int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
uint32 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 ((sbuf->st_mode & S_IWUSR) == 0)
result |= aRONLY;
if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
result |= aARCH;
if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
result |= aARCH;
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 (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 (S_ISDIR(sbuf->st_mode))
result = aDIR | (result & aRONLY);
if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) {
result |= FILE_ATTRIBUTE_SPARSE;
}
#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;
}
/* 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;
}
/* 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"));
DEBUG(8,("\n"));
return(result);
return(result);
}
/*******************************************************************

View File

@ -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(fsp->print_jobid, data, n);
return print_job_write(SNUM(fsp->conn), fsp->print_jobid, data, n);
if (!fsp->can_write) {
errno = EPERM;

View File

@ -29,7 +29,6 @@
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);

View File

@ -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",queue->job); /* uJobId */
PACKI(desc,"W",pjobid_to_rap(snum,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,11 +2181,14 @@ 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);
int jobid, errcode;
uint32 jobid;
int snum;
int errcode;
extern struct current_user current_user;
WERROR werr = WERR_OK;
jobid = SVAL(p,0);
if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
return False;
/* check it's a supported varient */
if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
@ -2195,7 +2198,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
*rparam = REALLOC(*rparam,*rparam_len);
*rdata_len = 0;
if (!print_job_exists(jobid)) {
if (!print_job_exists(snum, jobid)) {
errcode = NERR_JobNotFound;
goto out;
}
@ -2204,15 +2207,15 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
switch (function) {
case 81: /* delete */
if (print_job_delete(&current_user, jobid, &werr))
if (print_job_delete(&current_user, snum, jobid, &werr))
errcode = NERR_Success;
break;
case 82: /* pause */
if (print_job_pause(&current_user, jobid, &werr))
if (print_job_pause(&current_user, snum, jobid, &werr))
errcode = NERR_Success;
break;
case 83: /* resume */
if (print_job_resume(&current_user, jobid, &werr))
if (print_job_resume(&current_user, snum, jobid, &werr))
errcode = NERR_Success;
break;
}
@ -2313,12 +2316,14 @@ 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);
int jobid;
uint32 jobid;
int snum;
int uLevel = SVAL(p,2);
int function = SVAL(p,4);
int place, errcode;
jobid = SVAL(p,0);
if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
return False;
*rparam_len = 4;
*rparam = REALLOC(*rparam,*rparam_len);
@ -2329,7 +2334,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(jobid)) {
if (!print_job_exists(snum, jobid)) {
errcode=NERR_JobNotFound;
goto out;
}
@ -2341,14 +2346,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(jobid, place)) {
if (print_job_set_place(snum, jobid, place)) {
errcode=NERR_Success;
}
break;
case 0xb:
/* change print job name, data gives the name */
if (print_job_set_name(jobid, data)) {
if (print_job_set_name(snum, jobid, data)) {
errcode=NERR_Success;
}
break;
@ -2994,7 +2999,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
int count;
int i;
int snum;
int job;
uint32 jobid;
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
@ -3011,14 +3016,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;
job = SVAL(p,0);
snum = print_job_snum(job);
if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
return False;
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 == job) break;
if (queue[i].job == jobid) break;
}
if (mdrcnt > 0) {
@ -3549,7 +3554,7 @@ static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,cha
struct
const static struct
{
char *name;
int id;

View File

@ -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;

View File

@ -23,7 +23,6 @@
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;
@ -200,14 +199,11 @@ 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, ads->realm);
asprintf(&principal, "HOST/%s@%s", guid, lp_realm());
blob = spnego_gen_negTokenInit(guid, OIDs_krb5, principal);
free(principal);
ads_destroy(&ads);
}
memcpy(p, blob.data, blob.length);
len = blob.length;
@ -288,10 +284,12 @@ 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"));
@ -412,8 +410,17 @@ 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++;

File diff suppressed because it is too large Load Diff

View File

@ -89,29 +89,6 @@ 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.
****************************************************************************/
@ -207,7 +184,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, char *smb_name)
int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
{
user_struct *vuser = NULL;
uid_t uid;
@ -297,7 +274,7 @@ int register_vuid(auth_serversupplied_info *server_info, 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,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name));
DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid));
next_vuid++;
num_validated_vuids++;
@ -311,8 +288,9 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name)
}
/* Register a home dir service for this user */
if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)
&& (lp_servicenumber(vuser->user.unix_name) < 0)) {
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));
vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir);
} else {
vuser->homes_snum = -1;
@ -325,7 +303,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name)
/****************************************************************************
add a name to the session users list
****************************************************************************/
void add_session_user(char *user)
void add_session_user(const char *user)
{
fstring suser;
StrnCpy(suser,user,sizeof(suser)-1);
@ -373,7 +351,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));
char **user_list = str_list_make (lp_username(snum), NULL);
if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) {
ret = user_in_list(user, user_list);
}

View File

@ -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;

View File

@ -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 milli seconds
The timeout is in milliseconds
****************************************************************************/
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!
*/
static struct smb_message_struct
const static struct smb_message_struct
{
char *name;
const char *name;
int (*fn)(connection_struct *conn, char *, char *, int, int);
int flags;
}
@ -386,7 +386,7 @@ 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 | QUEUE_IN_OPLOCK},
/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
/* 0x26 */ { "SMBtranss",NULL,AS_USER | CAN_IPC},
/* 0x27 */ { "SMBioctl",reply_ioctl,0},
/* 0x28 */ { "SMBioctls",NULL,AS_USER},
@ -399,7 +399,7 @@ 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 | QUEUE_IN_OPLOCK | CAN_IPC },
/* 0x32 */ { "SMBtrans2", reply_trans2, AS_USER | CAN_IPC },
/* 0x33 */ { "SMBtranss2", reply_transs2, AS_USER},
/* 0x34 */ { "SMBfindclose", reply_findclose,AS_USER},
/* 0x35 */ { "SMBfindnclose", reply_findnclose, AS_USER},
@ -611,7 +611,7 @@ static struct smb_message_struct
/*******************************************************************
dump a prs to a file
********************************************************************/
static void smb_dump(char *name, int type, char *data, ssize_t len)
static void smb_dump(const 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
****************************************************************************/
char *smb_fn_name(int type)
const char *smb_fn_name(int type)
{
static char *unknown_name = "SMBunknown";
@ -1228,13 +1228,6 @@ 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();

View File

@ -38,7 +38,6 @@ 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;
@ -53,10 +52,11 @@ 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,6 +65,11 @@ 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 ||
@ -77,24 +82,19 @@ int reply_special(char *inbuf,char *outbuf)
DEBUG(2,("netbios connect: name1=%s name2=%s\n",
name1,name2));
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);
name1[15] = 0;
fstrcpy(local_machine,name1);
len = strlen(local_machine);
len = strlen(name2);
if (len == 16) {
name_type = local_machine[15];
local_machine[15] = 0;
name_type = name2[15];
name2[15] = 0;
}
trim_string(local_machine," "," ");
strlower(local_machine);
alpha_strcpy(local_machine,local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
set_local_machine_name(name1);
set_remote_machine_name(name2);
DEBUG(2,("netbios connect: local=%s remote=%s\n",
local_machine, remote_machine ));
get_local_machine_name(), get_remote_machine_name() ));
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(remote_machine);
add_session_user(get_remote_machine_name());
}
reload_services(True);
@ -115,6 +115,7 @@ int reply_special(char *inbuf,char *outbuf)
claim_connection(NULL,"",MAXSTATUS,True);
already_got_session = True;
break;
case 0x89: /* session keepalive request
@ -148,7 +149,8 @@ int reply_special(char *inbuf,char *outbuf)
int reply_tcon(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring service;
const char *service;
pstring service_buf;
pstring password;
pstring dev;
int outsize = 0;
@ -160,17 +162,19 @@ int reply_tcon(connection_struct *conn,
START_PROFILE(SMBtcon);
*service = *password = *dev = 0;
*service_buf = *password = *dev = 0;
p = smb_buf(inbuf)+1;
p += srvstr_pull_buf(inbuf, service, p, sizeof(service), STR_TERMINATE) + 1;
p += srvstr_pull_buf(inbuf, service_buf, 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,'\\');
p = strrchr_m(service_buf,'\\');
if (p) {
pstrcpy(service, p+1);
service = p+1;
} else {
service = service_buf;
}
password_blob = data_blob(password, pwlen+1);
@ -354,10 +358,13 @@ int reply_ioctl(connection_struct *conn,
switch (ioctl_code)
{
case IOCTL_QUERY_JOB_INFO:
SSVAL(p,0,fsp->print_jobid); /* Job number */
{
uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid);
SSVAL(p,0,rap_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);
@ -2744,6 +2751,8 @@ 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);

View File

@ -38,8 +38,6 @@ 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 :(
@ -133,7 +131,7 @@ static BOOL open_sockets_inetd(void)
smbd_set_server_fd(dup(0));
/* close our standard file descriptors */
close_low_fds();
close_low_fds(False); /* Don't close stderr */
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
set_socket_options(smbd_server_fd(), user_socket_options);
@ -151,13 +149,15 @@ static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len)
Open the socket communication.
****************************************************************************/
static BOOL open_sockets(BOOL is_daemon,int port)
static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
{
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,73 +176,106 @@ static BOOL open_sockets(BOOL is_daemon,int port)
/* Stop zombies */
CatchChild();
FD_ZERO(&listen_set);
if(lp_interfaces() && lp_bind_interfaces_only()) {
/* 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()) {
/* 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: interface %d has NULL IP address !\n", i));
DEBUG(0,("open_sockets_smbd: 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;
/* ready to listen */
set_socket_options(s,"SO_KEEPALIVE");
set_socket_options(s,user_socket_options);
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);
if (listen(s, 5) == -1) {
DEBUG(0,("listen: %s\n",strerror(errno)));
close(s);
return False;
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;
}
}
FD_SET(s,&listen_set);
}
} else {
/* Just bind to 0.0.0.0 - accept connections
from anywhere. */
fstring tok;
char *ptr;
num_interfaces = 1;
/* open an incoming socket */
s = open_socket_in(SOCK_STREAM, port, 0,
interpret_addr(lp_socket_address()),True);
if (s == -1)
return(False);
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);
/* 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,("open_sockets_smbd: listen: %s\n",
strerror(errno)));
close(s);
return False;
}
if (listen(s, 5) == -1) {
DEBUG(0,("open_sockets: 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;
}
}
fd_listenset[0] = s;
FD_SET(s,&listen_set);
}
SAFE_FREE(ports);
/* Listen to messages */
message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
@ -293,7 +326,7 @@ max can be %d\n",
socklen_t in_addrlen = sizeof(addr);
s = -1;
for(i = 0; i < num_interfaces; i++) {
for(i = 0; i < num_sockets; i++) {
if(FD_ISSET(fd_listenset[i],&lfds)) {
s = fd_listenset[i];
/* Clear this so we don't look
@ -309,7 +342,7 @@ max can be %d\n",
continue;
if (smbd_server_fd() == -1) {
DEBUG(0,("open_sockets: accept: %s\n",
DEBUG(0,("open_sockets_smbd: accept: %s\n",
strerror(errno)));
continue;
}
@ -318,17 +351,21 @@ max can be %d\n",
/* Child code ... */
/* close the listening socket(s) */
for(i = 0; i < num_interfaces; i++)
for(i = 0; i < num_sockets; i++)
close(fd_listenset[i]);
/* close our standard file
descriptors */
close_low_fds();
close_low_fds(False);
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. */
@ -382,8 +419,6 @@ BOOL reload_services(BOOL test)
{
BOOL ret;
set_register_printer_fn();
if (lp_loaded()) {
pstring fname;
pstrcpy(fname,lp_configfile());
@ -611,7 +646,7 @@ static void usage(char *pname)
BOOL is_daemon = False;
BOOL interactive = False;
BOOL specified_logfile = False;
int port = SMB_PORT;
char *ports = NULL;
int opt;
pstring logfile;
@ -666,7 +701,7 @@ static void usage(char *pname)
break;
case 'p':
port = atoi(optarg);
ports = optarg;
break;
case 'h':
@ -705,7 +740,7 @@ static void usage(char *pname)
lp_set_logfile(logfile);
}
fstrcpy(remote_machine, "smbd");
set_remote_machine_name("smbd");
setup_logging(argv[0],interactive);
@ -773,11 +808,6 @@ 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"));
@ -839,13 +869,15 @@ static void usage(char *pname)
start_background_queue();
*/
if (!open_sockets(is_daemon,port))
if (!open_sockets_smbd(is_daemon,ports))
exit(1);
/*
* everything after this point is run after the fork()
*/
namecache_enable();
if (!locking_init(0))
exit(1);
@ -889,6 +921,13 @@ 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();

View File

@ -27,9 +27,7 @@ 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;
/****************************************************************************
@ -104,7 +102,9 @@ int add_home_service(const char *service, const char *username, const char *home
}
}
lp_add_home(service, iHomeService, username, homedir);
if (!lp_add_home(service, iHomeService, username, homedir)) {
return -1;
}
return lp_servicenumber(service);
@ -347,7 +347,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
}
if (lp_guest_only(snum)) {
char *guestname = lp_guestaccount();
const 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\n",s));
DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum)));
}
/* 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",
remote_machine, conn->client_address,
get_remote_machine_name(), 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\n", conn->connectpath));
DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn))));
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) ", remote_machine, conn->client_address );
dbgtext( "%s (%s) ", get_remote_machine_name(), 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,6 +759,7 @@ 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;
}
}
@ -773,12 +774,15 @@ 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(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);
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;
}
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. */
@ -797,7 +801,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
}
}
} else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
&& strequal(service, lp_servicename(vuser->homes_snum))) {
&& strequal(service_in, 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,
@ -819,7 +823,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
}
DEBUG(0,("%s (%s) couldn't find service %s\n",
remote_machine, client_addr(), service));
get_remote_machine_name(), client_addr(), service));
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
}
@ -841,7 +845,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",
remote_machine,conn->client_address,
get_remote_machine_name(),conn->client_address,
lp_servicename(SNUM(conn))));
if (conn->vfs_ops.disconnect != NULL) {

View File

@ -27,21 +27,22 @@
#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;
int i = 0;
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_id = 0;
vuser->session_keystr = NULL;
/* don't register sessions for the guest user - its just too
expensive to go through pam session code for browsing etc */
@ -63,18 +64,37 @@ BOOL session_claim(user_struct *vuser)
data.dptr = NULL;
data.dsize = 0;
for (i=1;i<MAX_SESSION_ID;i++) {
slprintf(keystr, sizeof(keystr)-1, "ID/%d", i);
#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);
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;
tdb_store_flag = TDB_REPLACE;
}
/* If 'hostname lookup' == yes, then do the DNS lookup. This is
@ -90,24 +110,25 @@ BOOL session_claim(user_struct *vuser)
fstrcpy(sessionid.username, vuser->user.unix_name);
fstrcpy(sessionid.hostname, hostname);
slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_TEMPLATE, i);
sessionid.id_num = i;
sessionid.id_num = i; /* Only valid for utmp sessions */
sessionid.pid = pid;
sessionid.uid = vuser->uid;
sessionid.gid = vuser->gid;
fstrcpy(sessionid.remote_machine, remote_machine);
fstrcpy(sessionid.remote_machine, get_remote_machine_name());
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));
tdb_delete(tdb, key);
if (tdb_store_flag == TDB_MODIFY) {
tdb_delete(tdb, key);
}
return False;
}
data.dptr = (char *)&sessionid;
data.dsize = sizeof(sessionid);
if (tdb_store(tdb, key, data, TDB_MODIFY) != 0) {
if (tdb_store(tdb, key, data, tdb_store_flag) != 0) {
DEBUG(1,("session_claim: unable to create session id record\n"));
return False;
}
@ -119,7 +140,11 @@ BOOL session_claim(user_struct *vuser)
}
#endif
vuser->session_id = i;
vuser->session_keystr = strdup(keystr);
if (!vuser->session_keystr) {
DEBUG(0, ("session_claim: strdup() failed for session_keystr\n"));
return False;
}
return True;
}
@ -129,18 +154,15 @@ void session_yield(user_struct *vuser)
TDB_DATA dbuf;
struct sessionid sessionid;
TDB_DATA key;
fstring keystr;
if (!tdb) return;
if (vuser->session_id == 0) {
if (!vuser->session_keystr) {
return;
}
slprintf(keystr, sizeof(keystr)-1, "ID/%d", vuser->session_id);
key.dptr = keystr;
key.dsize = strlen(keystr)+1;
key.dptr = vuser->session_keystr;
key.dsize = strlen(vuser->session_keystr)+1;
dbuf = tdb_fetch(tdb, key);

View File

@ -3,6 +3,7 @@
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
@ -122,6 +123,12 @@ 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"));
@ -139,7 +146,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
}
*p = 0;
if (strcasecmp(p+1, ads->realm) != 0) {
if (strcasecmp(p+1, ads->auth.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);
@ -200,7 +207,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)
DATA_BLOB blob, uint32 errcode)
{
char *p;
@ -209,7 +216,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, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
SIVAL(outbuf, smb_rcls, errcode);
SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
SSVAL(outbuf, smb_vwv3, blob.length);
p = smb_buf(outbuf);
@ -236,11 +243,12 @@ 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, extra_data;
DATA_BLOB chal, spnego_chal;
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)) {
@ -258,7 +266,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) {
if (got_kerberos && (SEC_ADS == lp_security())) {
int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
length, bufsize, &secblob);
data_blob_free(&secblob);
@ -271,19 +279,16 @@ static int reply_spnego_negotiate(connection_struct *conn,
file_save("secblob.dat", secblob.data, secblob.length);
#endif
if (!msrpc_parse(&secblob, "CddB",
if (!msrpc_parse(&secblob, "CddAA",
"NTLMSSP",
&ntlmssp_command,
&neg_flags,
&extra_data)) {
&cliname,
&domname)) {
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);
@ -307,41 +312,44 @@ static int reply_spnego_negotiate(connection_struct *conn,
return the flags we want. Obviously this is not correct */
chal_flags = NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_LM_KEY |
NTLMSSP_NEGOTIATE_128 |
NTLMSSP_NEGOTIATE_NTLM |
NTLMSSP_CHAL_TARGET_INFO;
{
DATA_BLOB domain_blob, netbios_blob, realm_blob;
DATA_BLOB domain_blob, struct_blob;
fstring dnsname, dnsdomname;
msrpc_gen(&domain_blob,
"U",
lp_workgroup());
msrpc_gen(&netbios_blob,
"U",
global_myname);
msrpc_gen(&realm_blob,
"U",
lp_realm());
fstrcpy(dnsdomname, lp_realm());
strlower(dnsdomname);
msrpc_gen(&chal, "CddddbBBBB",
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(&chal, "CdUdbddB",
"NTLMSSP",
NTLMSSP_CHALLENGE,
0,
0x30, /* ?? */
lp_workgroup(),
chal_flags,
cryptkey, 8,
domain_blob.data, domain_blob.length,
domain_blob.data, domain_blob.length,
netbios_blob.data, netbios_blob.length,
realm_blob.data, realm_blob.length);
0, 0,
struct_blob.data, struct_blob.length);
data_blob_free(&domain_blob);
data_blob_free(&netbios_blob);
data_blob_free(&realm_blob);
data_blob_free(&struct_blob);
}
if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) {
@ -351,7 +359,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);
reply_sesssetup_blob(conn, outbuf, spnego_chal, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
data_blob_free(&chal);
data_blob_free(&spnego_chal);
@ -368,7 +376,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
int length, int bufsize,
DATA_BLOB blob1)
{
DATA_BLOB auth;
DATA_BLOB auth, response;
char *workgroup = NULL, *user = NULL, *machine = NULL;
DATA_BLOB lmhash, nthash, sess_key;
DATA_BLOB plaintext_password = data_blob(NULL, 0);
@ -413,6 +421,13 @@ 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);
@ -481,8 +496,12 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
return chain_reply(inbuf,outbuf,length,bufsize);
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;
}
@ -594,7 +613,6 @@ 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;
@ -630,8 +648,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) {
return ERROR_DOS(ERRDOS,ERRbuftoosmall);
if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) {
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
if (doencrypt) {
@ -665,13 +683,6 @@ 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.
@ -689,19 +700,29 @@ 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 {
plaintext_password = data_blob(p, passlen1+1);
/* Ensure null termination */
plaintext_password.data[passlen1] = 0;
pstring pass;
srvstr_pull(inbuf, pass, smb_buf(inbuf),
sizeof(pass), passlen1, STR_TERMINATE);
plaintext_password = data_blob(pass, strlen(pass)+1);
}
p += passlen1 + passlen2;
@ -720,7 +741,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, remote_machine));
DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name()));
if (*user) {
if (global_spnego_negotiated) {

View File

@ -30,6 +30,19 @@ 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
@ -256,7 +269,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
size = sbuf.st_size;
size = get_file_size(sbuf);
fmode = dos_mode(conn,fname,&sbuf);
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
@ -453,7 +466,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
uint32 reskey=0;
int prev_dirpos=0;
int mode=0;
SMB_OFF_T size = 0;
SMB_OFF_T file_size = 0;
SMB_OFF_T allocation_size = 0;
uint32 len;
time_t mdate=0, adate=0, cdate=0;
@ -565,8 +578,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
continue;
}
size = sbuf.st_size;
allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
file_size = get_file_size(sbuf);
allocation_size = get_allocation_size(&sbuf);
mdate = sbuf.st_mtime;
adate = sbuf.st_atime;
cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
@ -578,7 +591,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
}
if(mode & aDIR)
size = 0;
file_size = 0;
DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
@ -602,7 +615,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)size);
SIVAL(p,l1_cbFile,(uint32)file_size);
SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l1_attrFile,mode);
p += l1_achName;
@ -621,7 +634,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)size);
SIVAL(p,l2_cbFile,(uint32)file_size);
SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l2_attrFile,mode);
SIVAL(p,l2_cbList,0); /* No extended attributes */
@ -641,7 +654,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,size);
SOFF_T(p,0,file_size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@ -675,7 +688,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,size);
SOFF_T(p,0,file_size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@ -696,7 +709,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,size);
SOFF_T(p,0,file_size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@ -735,14 +748,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,sbuf.st_size); /* File size 64 Bit */
SOFF_T(p,0,get_file_size(sbuf)); /* 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,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
SOFF_T(p,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
#endif
p+= 8;
@ -1528,7 +1541,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint16 tran_call = SVAL(inbuf, smb_setup0);
uint16 info_level;
int mode=0;
SMB_OFF_T size=0;
SMB_OFF_T file_size=0;
SMB_OFF_T allocation_size=0;
unsigned int data_size;
SMB_STRUCT_STAT sbuf;
@ -1643,10 +1656,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
mode = dos_mode(conn,fname,&sbuf);
fullpathname = fname;
size = sbuf.st_size;
allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
file_size = get_file_size(sbuf);
allocation_size = get_allocation_size(&sbuf);
if (mode & aDIR)
size = 0;
file_size = 0;
params = Realloc(*pparams,2);
if (params == NULL)
@ -1692,7 +1705,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)size);
SIVAL(pdata,l1_cbFile,(uint32)file_size);
SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode);
SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
@ -1703,7 +1716,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)size);
SIVAL(pdata,12,(uint32)file_size);
SIVAL(pdata,16,(uint32)allocation_size);
SIVAL(pdata,20,mode);
break;
@ -1747,9 +1760,8 @@ 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,size);
SOFF_T(pdata,8,file_size);
SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,0);
SCVAL(pdata,21,(mode&aDIR)?1:0);
@ -1794,7 +1806,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,size);
SOFF_T(pdata,0,file_size);
break;
case SMB_QUERY_FILE_ALL_INFO:
@ -1805,7 +1817,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,32,mode);
pdata += 40;
SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,size);
SOFF_T(pdata,8,file_size);
SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,delete_pending);
SCVAL(pdata,21,(mode&aDIR)?1:0);
@ -1917,7 +1929,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,size);
SOFF_T(pdata,8,file_size);
SIVAL(pdata,16,allocation_size);
SIVAL(pdata,20,0); /* ??? */
data_size = 24 + byte_len;
@ -1925,7 +1937,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
case SMB_FILE_COMPRESSION_INFORMATION:
SOFF_T(pdata,0,size);
SOFF_T(pdata,0,allocation_size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
data_size = 16;
@ -1937,7 +1949,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,size);
SOFF_T(pdata,40,file_size);
SIVAL(pdata,48,mode);
SIVAL(pdata,52,0); /* ??? */
data_size = 56;
@ -1957,14 +1969,14 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
SOFF_T(pdata,0,sbuf.st_size); /* File size 64 Bit */
SOFF_T(pdata,0,get_file_size(sbuf)); /* 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,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
SOFF_T(pdata,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
#endif
pdata += 8;
@ -2246,7 +2258,8 @@ 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.
@ -2310,7 +2323,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
sbuf.st_mtime = fsp->pending_modtime;
}
size = sbuf.st_size;
size = get_file_size(sbuf);
tvs.modtime = sbuf.st_mtime;
tvs.actime = sbuf.st_atime;
dosmode = dos_mode(conn,fname,&sbuf);
@ -2413,7 +2426,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 != sbuf.st_size) {
if(allocation_size != get_file_size(sbuf)) {
SMB_STRUCT_STAT new_sbuf;
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
@ -2459,8 +2472,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (ret == -1)
return ERROR_NT(NT_STATUS_DISK_FULL);
/* Allocate can trucate size... */
size = new_sbuf.st_size;
/* Allocate can truncate size... */
size = get_file_size(new_sbuf);
}
break;
@ -2715,7 +2728,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* changing the size of a file.
*/
if (!size)
size = sbuf.st_size;
size = get_file_size(sbuf);
}
/*
@ -2757,7 +2770,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
}
if(size != sbuf.st_size) {
if (size != get_file_size(sbuf)) {
int ret;
@ -2970,9 +2983,11 @@ 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);
@ -2981,7 +2996,8 @@ 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. */
SSVAL(pdata,0,fsp->print_jobid); /* Job number */
rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); /* Job number */
SSVAL(pdata,0,rap_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);

View File

@ -440,44 +440,43 @@ 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 ret = False;
BOOL local_lookup = False;
*name_type = SID_NAME_UNKNOWN;
/* If we are looking up a domain user, make sure it is
for the local machine only */
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
if (strequal(global_myname, domain)) {
local_lookup = True;
} else if (lp_server_role() == ROLE_DOMAIN_PDC ||
lp_server_role() == ROLE_DOMAIN_PDC) {
if (strequal(domain, global_myworkgroup)) {
ret = local_lookup_name(name, psid, name_type);
local_lookup = 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));
}
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;
}
}
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));
DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
local_lookup ? "local" : "winbind", domain, name));
return False;
}
@ -593,13 +592,17 @@ 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(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
BOOL sid_to_uid(const 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) {
return local_sid_to_uid(puid, psid, sidtype);
BOOL result;
become_root();
result = local_sid_to_uid(puid, psid, sidtype);
unbecome_root();
return result;
}
/* (tridge) I commented out the slab of code below in order to support foreign SIDs
@ -665,7 +668,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
was done correctly, False if not.
*****************************************************************/
BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
{
fstring dom_name, name, sid_str;
enum SID_NAME_USE name_type;
@ -676,16 +679,21 @@ BOOL sid_to_gid(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 - trying local.\n",
DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
sid_to_string(sid_str, psid) ));
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;
}
/* this was probably a foreign sid - assume its a group rid
and continue */
name_type = SID_NAME_DOM_GRP;
}
/*
@ -696,7 +704,7 @@ BOOL sid_to_gid(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 local_sid_to_gid(pgid, psid, sidtype);
return False;
}
*sidtype = name_type;

View File

@ -3,6 +3,7 @@
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
@ -17,6 +18,8 @@
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"
@ -28,6 +31,12 @@ 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. */
@ -117,58 +126,75 @@ static struct vfs_ops default_vfs_ops = {
initialise default vfs hooks
****************************************************************************/
static BOOL vfs_init_default(connection_struct *conn)
static void vfs_init_default(connection_struct *conn)
{
DEBUG(3, ("Initialising default vfs hooks\n"));
memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(struct vfs_ops));
return True;
conn->vfs_private = NULL;
}
/****************************************************************************
initialise custom vfs hooks
****************************************************************************/
static BOOL vfs_init_custom(connection_struct *conn)
static BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
{
int vfs_version = -1;
struct vfs_ops *ops, *(*init_fptr)(int *, struct vfs_ops *);
vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *);
int i;
DEBUG(3, ("Initialising custom vfs hooks from %s\n", lp_vfsobj(SNUM(conn))));
DEBUG(3, ("Initialising custom vfs hooks from %s\n", vfs_object));
/* Open object file */
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()));
if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) {
DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror()));
return False;
}
/* Get handle on vfs_init() symbol */
init_fptr = (struct vfs_ops *(*)(int *, struct vfs_ops *))sys_dlsym(conn->dl_handle, "vfs_init");
init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init");
if (init_fptr == NULL) {
DEBUG(0, ("No vfs_init() symbol found in %s\n", lp_vfsobj(SNUM(conn))));
DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object));
return False;
}
/* Initialise vfs_ops structure */
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));
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;
}
return True;
@ -180,21 +206,70 @@ static BOOL vfs_init_custom(connection_struct *conn)
BOOL smbd_vfs_init(connection_struct *conn)
{
if (*lp_vfsobj(SNUM(conn))) {
/* Loadable object file */
if (!vfs_init_custom(conn)) {
DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed\n"));
return False;
}
return True;
}
char **vfs_objects, *vfsobj, *vfs_module, *vfs_path;
int nobj, i;
struct smb_vfs_handle_struct *handle;
/* Normal share - initialise with disk access functions */
return vfs_init_default(conn);
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;
}
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;
}
/*******************************************************************