1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

simple mods to add msrpc pipe redirection. default behaviour: fall back

to using internal msrpc code in smbd.
(This used to be commit 8976e26d46cb991710bc77463f7f928ac00dd4d8)
This commit is contained in:
Luke Leighton 2000-01-03 19:19:48 +00:00
parent 632b4f806e
commit fbd17c8daf
24 changed files with 3545 additions and 1242 deletions

View File

@ -96,7 +96,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/signal.o lib/slprintf.o lib/system.o lib/doscalls.o lib/time.o \
lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/crc32.o lib/snprintf.o \
lib/util_str.o lib/util_sid.o \
lib/util_array.o lib/util_str.o lib/util_sid.o \
lib/util_unistr.o lib/util_file.o \
lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o lib/fnmatch.o \
tdb/tdb.o
@ -116,7 +116,7 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o \
rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o \
rpc_server/srv_samr.o rpc_server/srv_srvsvc.o \
rpc_server/srv_util.o rpc_server/srv_wkssvc.o \
rpc_server/srv_pipe.o
rpc_server/srv_pipe_srv.o rpc_server/srv_pipe.o
RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \
rpc_parse/parse_net.o rpc_parse/parse_prs.o \
@ -148,6 +148,8 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
smbd/$(QUOTAOBJS) smbd/reply.o smbd/trans2.o smbd/uid.o \
smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \
lib/msrpc-client.o lib/msrpc_use.o \
rpc_parse/parse_creds.o \
smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o
PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o \

View File

@ -1,3 +1,3 @@
#!/bin/sh
export CFLAGS="-g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align"
export CFLAGS="-g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -DDEBUG_PASSWORD"
./configure

View File

@ -56,21 +56,6 @@ struct print_job_info
time_t t;
};
struct pwd_info
{
BOOL null_pwd;
BOOL cleartext;
BOOL crypted;
fstring password;
uchar smb_lm_pwd[16];
uchar smb_nt_pwd[16];
uchar smb_lm_owf[24];
uchar smb_nt_owf[24];
};
struct cli_state {
int port;
int fd;

View File

@ -131,6 +131,10 @@ typedef struct pipes_struct
/* When replying to an SMBtrans, this is the maximum amount of
data that can be sent in the initial reply. */
int max_trans_reply;
/* remote, server-side rpc redirection */
struct msrpc_state *m;
} pipes_struct;
struct api_struct

View File

@ -70,6 +70,7 @@ int dos_mkdir(char *dname,mode_t mode);
int dos_rmdir(char *dname);
int dos_chdir(char *dname);
int dos_utime(char *fname,struct utimbuf *times);
int copy_reg(char *source, const char *dest);
int dos_rename(char *from, char *to);
int dos_chmod(char *fname,mode_t mode);
char *dos_getwd(char *unix_path);
@ -125,6 +126,36 @@ void initialize_multibyte_vectors( int client_codepage);
void mdfour(unsigned char *out, unsigned char *in, int n);
/*The following definitions come from lib/msrpc-client.c */
BOOL receive_msrpc(int fd, prs_struct *data, unsigned int timeout);
BOOL msrpc_send(int fd, prs_struct *ps);
BOOL msrpc_receive(int fd, prs_struct *ps);
BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name);
void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_creds *usr);
void msrpc_close_socket(struct msrpc_state *msrpc);
void msrpc_sockopt(struct msrpc_state *msrpc, char *options);
BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
const char* pipename,
const struct user_creds *usr);
struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc);
void msrpc_shutdown(struct msrpc_state *msrpc);
BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
const char *pipe_name);
/*The following definitions come from lib/msrpc_use.c */
void init_msrpc_use(void);
void free_msrpc_use(void);
struct msrpc_state *msrpc_use_add(const char* pipe_name,
const struct user_creds *usr_creds,
BOOL redir);
BOOL msrpc_use_del(const char* pipe_name,
const struct user_creds *usr_creds,
BOOL force_close,
BOOL *connection_closed);
void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use);
/*The following definitions come from lib/pidfile.c */
pid_t pidfile_pid(char *name);
@ -234,6 +265,7 @@ void putip(void *dest,void *src);
char *dns_to_netbios_name(char *dns_name);
int name_mangle( char *In, char *Out, char name_type );
BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf);
int file_rename(char *from, char *to);
time_t file_modtime(char *fname);
BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st);
SMB_OFF_T get_file_size(char *file_name);
@ -310,6 +342,23 @@ void *memdup(void *p, size_t size);
char *myhostname(void);
char *lock_path(char *name);
/*The following definitions come from lib/util_array.c */
void free_void_array(uint32 num_entries, void **entries,
void(free_item)(void*));
void* add_copy_to_array(uint32 *len, void ***array, const void *item,
void*(item_dup)(const void*), BOOL alloc_anyway);
void* add_item_to_array(uint32 *len, void ***array, void *item);
void free_use_info_array(uint32 num_entries, struct use_info **entries);
struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array,
const struct use_info *name);
void free_char_array(uint32 num_entries, char **entries);
char* add_chars_to_array(uint32 *len, char ***array, const char *name);
void free_uint32_array(uint32 num_entries, uint32 **entries);
uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name);
void free_sid_array(uint32 num_entries, DOM_SID **entries);
DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid);
/*The following definitions come from lib/util_file.c */
BOOL do_file_lock(int fd, int waitsecs, int type);
@ -345,11 +394,14 @@ char *sid_to_string(fstring sidstr_out, DOM_SID *sid);
BOOL string_to_sid(DOM_SID *sidout, char *sidstr);
BOOL sid_append_rid(DOM_SID *sid, uint32 rid);
BOOL sid_split_rid(DOM_SID *sid, uint32 *rid);
void sid_copy(DOM_SID *dst, DOM_SID *src);
void sid_copy(DOM_SID *dst, const DOM_SID *src);
DOM_SID *sid_dup(DOM_SID *src);
BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid);
BOOL sid_equal(DOM_SID *sid1, DOM_SID *sid2);
size_t sid_size(DOM_SID *sid);
BOOL read_sid(char *sam_name, DOM_SID *sid);
BOOL write_sid(char *sam_name, DOM_SID *sid);
BOOL create_new_sid(DOM_SID *sid);
/*The following definitions come from lib/util_sock.c */
@ -374,6 +426,9 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
void reset_globals_after_fork(void);
char *client_name(int fd);
char *client_addr(int fd);
int open_pipe_sock(char *path);
int create_pipe_socket(char *dir, int dir_perms,
char *path, int path_perms);
/*The following definitions come from lib/util_str.c */
@ -645,6 +700,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
void pwd_init(struct pwd_info *pwd);
void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key);
BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2);
void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt);
void pwd_set_nullpwd(struct pwd_info *pwd);
void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
@ -684,7 +740,8 @@ char *smb_errstr(char *inbuf);
void unexpected_packet(struct packet_struct *p);
void clear_unexpected(time_t t);
struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, char *mailslot_name);
struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
char *mailslot_name);
/*The following definitions come from locking/locking.c */
@ -1355,7 +1412,7 @@ void pdb_set_last_set_time(char *p, int max_len, time_t t);
void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl);
BOOL pdb_gethexpwd(char *p, unsigned char *pwd);
BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid);
BOOL pdb_generate_sam_sid(void);
BOOL pdb_generate_sam_sid(char *domain_name, DOM_SID *sid);
uid_t pdb_user_rid_to_uid(uint32 user_rid);
gid_t pdb_user_rid_to_gid(uint32 user_rid);
uint32 pdb_uid_to_user_rid(uid_t uid);
@ -1581,6 +1638,45 @@ BOOL do_wks_query_info(struct cli_state *cli,
char *server_name, uint32 switch_value,
WKS_INFO_100 *wks100);
/*The following definitions come from rpc_parse/parse_creds.c */
BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
const char* requested_name,
const char* real_name,
BOOL guest);
BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth);
void creds_free_unix(CREDS_UNIX *r_u);
BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps);
BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth);
void creds_free_unix_sec(CREDS_UNIX_SEC *r_u);
BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
DOM_SID *sid, uint32 num_grps, uint32 *grps);
BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth);
void creds_free_nt_sec(CREDS_NT_SEC *r_u);
BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth);
BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth);
void creds_free_nt(CREDS_NT *r_u);
BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth);
void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from);
void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from);
void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from);
void copy_nt_creds(struct ntuser_creds *to,
const struct ntuser_creds *from);
void copy_user_creds(struct user_creds *to,
const struct user_creds *from);
void free_user_creds(struct user_creds *creds);
BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth);
BOOL create_ntuser_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
const struct ntuser_creds *ntu,
BOOL reuse);
BOOL create_user_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
const struct user_creds *usr);
/*The following definitions come from rpc_parse/parse_lsa.c */
void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
@ -1769,6 +1865,7 @@ BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int
void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name);
BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io);
BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout);
void prs_mem_free(prs_struct *ps);
void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic);
char *prs_take_memory(prs_struct *ps, uint32 *psize);
@ -2245,10 +2342,10 @@ BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data);
/*The following definitions come from rpc_server/srv_pipe.c */
BOOL create_next_pdu(pipes_struct *p);
BOOL rpc_command(pipes_struct *p, char *input_data, int data_len);
BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
prs_struct *rpc_in);
BOOL readwrite_pipe(pipes_struct *p, char *data, int len,
char **rdata, int *rlen);
ssize_t write_pipe(pipes_struct *p, char *data, size_t n);
int read_pipe(pipes_struct *p, char *data, int n);
/*The following definitions come from rpc_server/srv_pipe_hnd.c */
@ -2266,6 +2363,13 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn);
pipes_struct *get_rpc_pipe_p(char *buf, int where);
pipes_struct *get_rpc_pipe(int pnum);
/*The following definitions come from rpc_server/srv_pipe_srv.c */
BOOL create_next_pdu(pipes_struct *p);
BOOL rpc_command(pipes_struct *p, char *input_data, int data_len);
BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
prs_struct *rpc_in);
/*The following definitions come from rpc_server/srv_reg.c */
BOOL api_reg_rpc(pipes_struct *p, prs_struct *data);

View File

@ -0,0 +1,92 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1999
Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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.
*/
#ifndef _RPC_CREDS_H /* _RPC_CREDS_H */
#define _RPC_CREDS_H
typedef struct ntuser_creds
{
fstring user_name;
fstring domain;
struct pwd_info pwd;
uint32 ntlmssp_flags;
} CREDS_NT;
typedef struct unixuser_creds
{
fstring user_name;
fstring requested_name;
fstring real_name;
BOOL guest;
} CREDS_UNIX;
typedef struct unixsec_creds
{
uint32 uid;
uint32 gid;
int num_grps;
uint32 *grps;
} CREDS_UNIX_SEC;
typedef struct ntsec_creds
{
DOM_SID sid;
uint32 num_grps;
uint32 *grp_rids;
} CREDS_NT_SEC;
typedef struct user_creds
{
BOOL reuse;
uint32 ptr_ntc;
uint32 ptr_uxc;
uint32 ptr_nts;
uint32 ptr_uxs;
CREDS_NT ntc;
CREDS_UNIX uxc;
CREDS_NT_SEC nts;
CREDS_UNIX_SEC uxs;
} CREDS_HYBRID;
typedef struct cred_command
{
uint16 version;
uint16 command;
fstring name;
uint32 ptr_creds;
CREDS_HYBRID *cred;
} CREDS_CMD;
#endif /* _RPC_CREDS_H */

View File

@ -438,6 +438,14 @@ struct sam_disp_info
char *full_name; /* user's full name string */
};
struct use_info
{
BOOL connected;
char *srv_name;
char *user_name;
char *domain;
};
#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
/* DOM_SID - security id */
@ -1768,6 +1776,59 @@ struct nmb_name {
unsigned int name_type;
};
#define AGENT_CMD_CON 0
#define AGENT_CMD_CON_ANON 2
#define AGENT_CMD_CON_REUSE 1
struct pwd_info
{
BOOL null_pwd;
BOOL cleartext;
BOOL crypted;
fstring password;
uchar smb_lm_pwd[16];
uchar smb_nt_pwd[16];
uchar smb_lm_owf[24];
uchar smb_nt_owf[128];
size_t nt_owf_len;
uchar lm_cli_chal[8];
uchar nt_cli_chal[128];
size_t nt_cli_chal_len;
uchar sess_key[16];
};
#include "rpc_creds.h"
struct ntdom_info
{
unsigned char sess_key[16]; /* Current session key. */
unsigned char ntlmssp_hash[258]; /* ntlmssp data. */
uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */
uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */
uint32 ntlmssp_seq_num; /* ntlmssp sequence number */
DOM_CRED clnt_cred; /* Client credential. */
int max_recv_frag;
int max_xmit_frag;
};
struct msrpc_state
{
fstring pipe_name;
struct user_creds usr;
struct ntdom_info nt;
int fd;
BOOL redirect;
BOOL initialised;
char *inbuf;
char *outbuf;
};
#include "client.h"
#include "rpcclient.h"

View File

@ -158,7 +158,7 @@ int dos_utime(char *fname,struct utimbuf *times)
<warrenb@hpcvscdp.cv.hp.com>
**********************************************************/
static int copy_reg(char *source, const char *dest)
int copy_reg(char *source, const char *dest)
{
SMB_STRUCT_STAT source_stats;
int ifd;

400
source3/lib/msrpc-client.c Normal file
View File

@ -0,0 +1,400 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB msrpcent generic functions
Copyright (C) Andrew Tridgell 1994-1999
Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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.
*/
#define NO_SYSLOG
#include "includes.h"
extern int DEBUGLEVEL;
/****************************************************************************
read an msrpc pdu from a fd.
The timeout is in milliseconds.
****************************************************************************/
BOOL receive_msrpc(int fd, prs_struct *data, unsigned int timeout)
{
BOOL ok;
size_t len;
RPC_HDR hdr;
prs_init(data, 0, 4, True);
ok = prs_read(data, fd, 16, timeout);
if (!ok)
{
prs_mem_free(data);
return False;
}
if (!smb_io_rpc_hdr("hdr", &hdr, data, 0))
{
prs_mem_free(data);
return False;
}
len = hdr.frag_len - 16;
if (len > 0)
{
ok = prs_read(data, fd, hdr.frag_len, 0);
if (!ok)
{
prs_mem_free(data);
return False;
}
data->data_offset = hdr.frag_len;
return True;
}
prs_mem_free(data);
return False;
}
/****************************************************************************
send an smb to a fd and re-establish if necessary
****************************************************************************/
BOOL msrpc_send(int fd, prs_struct *ps)
{
size_t len = ps != NULL ? ps->buffer_size : 0;
size_t nwritten=0;
ssize_t ret;
char *outbuf = ps->data_p;
DEBUG(10,("msrpc_send_prs: data: %p len %d\n", outbuf, len));
dbgflush();
dump_data(10, outbuf, len);
while (nwritten < len)
{
ret = write_socket(fd,outbuf+nwritten,len - nwritten);
if (ret <= 0)
{
DEBUG(0,("Error writing %d msrpc bytes. %d.\n",
len,ret));
prs_mem_free(ps);
return False;
}
nwritten += ret;
}
prs_mem_free(ps);
return True;
}
/****************************************************************************
receive msrpc packet
****************************************************************************/
BOOL msrpc_receive(int fd, prs_struct *ps)
{
int len;
DEBUG(10,("msrpc_receive: %d\n", __LINE__));
if (!receive_msrpc(fd, ps, 0))
{
return False;
}
len = ps->buffer_size;
if (ps->data_p == NULL || len <= 0)
{
return False;
}
dump_data(10, ps->data_p, len);
DEBUG(10,("msrpc_receive: len %d\n", len));
return True;
}
/****************************************************************************
open the msrpcent sockets
****************************************************************************/
BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name)
{
fstring path;
slprintf(path, sizeof(path)-1, "%s/.msrpc/%s", LOCKDIR, pipe_name);
fstrcpy(msrpc->pipe_name, pipe_name);
msrpc->fd = open_pipe_sock(path);
if (msrpc->fd == -1)
{
return False;
}
return True;
}
/****************************************************************************
initialise a msrpcent structure
****************************************************************************/
void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_creds *usr)
{
copy_user_creds(&msrpc->usr, usr);
}
/****************************************************************************
close the socket descriptor
****************************************************************************/
void msrpc_close_socket(struct msrpc_state *msrpc)
{
if (msrpc->fd != -1)
{
close(msrpc->fd);
}
msrpc->fd = -1;
}
/****************************************************************************
set socket options on a open connection
****************************************************************************/
void msrpc_sockopt(struct msrpc_state *msrpc, char *options)
{
set_socket_options(msrpc->fd, options);
}
static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
const struct user_creds *usr)
{
struct msrpc_state msrpc_redir;
int sock = msrpc->fd;
char *data;
prs_struct ps;
uint32 len;
char *in = msrpc->inbuf;
char *out = msrpc->outbuf;
uint16 command;
command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
if (!create_user_creds(&ps, msrpc->pipe_name, 0x0, command, usr))
{
DEBUG(0,("could not parse credentials\n"));
close(sock);
return False;
}
len = ps.data_offset;
data = ps.data_p;
SIVAL(data, 0, len);
#ifdef DEBUG_PASSWORD
DEBUG(100,("data len: %d\n", len));
dump_data(100, data, len);
#endif
if (write(sock, data, len) <= 0)
{
DEBUG(0,("write failed\n"));
return False;
}
if (msrpc->redirect)
{
len = read(sock, &msrpc_redir, sizeof(msrpc_redir));
if (len != sizeof(msrpc_redir))
{
DEBUG(0,("read failed\n"));
return False;
}
memcpy(msrpc, &msrpc_redir, sizeof(msrpc_redir));
msrpc->inbuf = in;
msrpc->outbuf = out;
msrpc->fd = sock;
msrpc->usr.reuse = False;
}
else
{
uint32 status;
len = read(sock, &status, sizeof(status));
return len == sizeof(status) && status == 0x0;
}
return True;
}
static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
const char* pipe_name,
const struct user_creds *usr)
{
int sock;
fstring path;
slprintf(path, sizeof(path)-1, "/tmp/.msrpc/.%s/agent", pipe_name);
sock = open_pipe_sock(path);
if (sock < 0)
{
return False;
}
msrpc->fd = sock;
if (!msrpc_authenticate(msrpc, usr))
{
DEBUG(0,("authenticate failed\n"));
close(msrpc->fd);
msrpc->fd = -1;
return False;
}
return True;
}
BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
const char* pipename,
const struct user_creds *usr)
{
ZERO_STRUCTP(msrpc);
if (!msrpc_initialise(msrpc))
{
DEBUG(0,("unable to initialise msrpcent connection.\n"));
return False;
}
msrpc_init_creds(msrpc, usr);
if (!msrpc_establish_connection(msrpc, pipename))
{
msrpc_shutdown(msrpc);
return False;
}
return True;
}
/****************************************************************************
initialise a msrpcent structure
****************************************************************************/
struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc)
{
if (!msrpc) {
msrpc = (struct msrpc_state *)malloc(sizeof(*msrpc));
if (!msrpc)
return NULL;
ZERO_STRUCTP(msrpc);
}
if (msrpc->initialised) {
msrpc_shutdown(msrpc);
}
ZERO_STRUCTP(msrpc);
msrpc->fd = -1;
msrpc->outbuf = (char *)malloc(CLI_BUFFER_SIZE+4);
msrpc->inbuf = (char *)malloc(CLI_BUFFER_SIZE+4);
if (!msrpc->outbuf || !msrpc->inbuf)
{
return False;
}
msrpc->initialised = 1;
msrpc_init_creds(msrpc, NULL);
return msrpc;
}
/****************************************************************************
shutdown a msrpcent structure
****************************************************************************/
void msrpc_shutdown(struct msrpc_state *msrpc)
{
DEBUG(10,("msrpc_shutdown\n"));
if (msrpc->outbuf)
{
free(msrpc->outbuf);
}
if (msrpc->inbuf)
{
free(msrpc->inbuf);
}
msrpc_close_socket(msrpc);
memset(msrpc, 0, sizeof(*msrpc));
}
/****************************************************************************
establishes a connection right up to doing tconX, reading in a password.
****************************************************************************/
BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
const char *pipe_name)
{
DEBUG(5,("msrpc_establish_connection: connecting to %s (%s) - %s\n",
pipe_name,
msrpc->usr.ntc.user_name, msrpc->usr.ntc.domain));
/* establish connection */
if ((!msrpc->initialised))
{
return False;
}
if (msrpc->fd == -1 && msrpc->redirect)
{
if (msrpc_init_redirect(msrpc, pipe_name, &msrpc->usr))
{
DEBUG(10,("msrpc_establish_connection: redirected OK\n"));
return True;
}
else
{
DEBUG(10,("redirect FAILED\n"));
return False;
}
}
if (msrpc->fd == -1)
{
if (!msrpc_connect(msrpc, pipe_name))
{
DEBUG(1,("msrpc_establish_connection: failed %s)\n",
pipe_name));
return False;
}
}
if (!msrpc_authenticate(msrpc, &msrpc->usr))
{
DEBUG(0,("authenticate failed\n"));
close(msrpc->fd);
msrpc->fd = -1;
return False;
}
return True;
}

328
source3/lib/msrpc_use.c Normal file
View File

@ -0,0 +1,328 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB client generic functions
Copyright (C) Andrew Tridgell 1994-1999
Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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.
*/
#define NO_SYSLOG
#include "includes.h"
#include "trans2.h"
extern int DEBUGLEVEL;
extern pstring scope;
extern pstring global_myname;
struct msrpc_use
{
struct msrpc_state *cli;
uint32 num_users;
};
static struct msrpc_use **msrpcs = NULL;
uint32 num_msrpcs = 0;
/****************************************************************************
terminate client connection
****************************************************************************/
static void msrpc_use_free(struct msrpc_use *cli)
{
if (cli->cli != NULL)
{
if (cli->cli->initialised)
{
msrpc_shutdown(cli->cli);
}
free(cli->cli);
}
free(cli);
}
/****************************************************************************
free a client array
****************************************************************************/
static void free_msrpc_array(uint32 num_entries, struct msrpc_use **entries)
{
void(*fn)(void*) = (void(*)(void*))&msrpc_use_free;
free_void_array(num_entries, (void**)entries, *fn);
}
/****************************************************************************
add a client state to the array
****************************************************************************/
static struct msrpc_use* add_msrpc_to_array(uint32 *len,
struct msrpc_use ***array,
struct msrpc_use *cli)
{
int i;
for (i = 0; i < num_msrpcs; i++)
{
if (msrpcs[i] == NULL)
{
msrpcs[i] = cli;
return cli;
}
}
return (struct msrpc_use*)add_item_to_array(len,
(void***)array, (void*)cli);
}
/****************************************************************************
initiate client array
****************************************************************************/
void init_msrpc_use(void)
{
msrpcs = NULL;
num_msrpcs = 0;
}
/****************************************************************************
terminate client array
****************************************************************************/
void free_msrpc_use(void)
{
free_msrpc_array(num_msrpcs, msrpcs);
init_msrpc_use();
}
/****************************************************************************
find client state. server name, user name, domain name and password must all
match.
****************************************************************************/
static struct msrpc_use *msrpc_find(const char* pipe_name,
const struct user_creds *usr_creds)
{
int i;
struct user_creds null_usr;
if (usr_creds == NULL)
{
copy_user_creds(&null_usr, usr_creds);
usr_creds = &null_usr;
}
DEBUG(10,("msrpc_find: %s %s %s\n",
pipe_name,
usr_creds->ntc.user_name,
usr_creds->ntc.domain));
for (i = 0; i < num_msrpcs; i++)
{
char *msrpc_name = NULL;
struct msrpc_use *c = msrpcs[i];
if (c == NULL) continue;
msrpc_name = c->cli->pipe_name;
DEBUG(10,("msrpc_find[%d]: %s %s %s\n",
i, msrpc_name,
c->cli->usr.ntc.user_name,
c->cli->usr.ntc.domain));
if (!strequal(msrpc_name, pipe_name))
{
continue;
}
if (!strequal(usr_creds->ntc.user_name, c->cli->usr.ntc.user_name))
{
continue;
}
if (!usr_creds->reuse &&
!pwd_compare(&usr_creds->ntc.pwd, &c->cli->usr.ntc.pwd))
{
DEBUG(100,("password doesn't match\n"));
continue;
}
if (usr_creds->ntc.domain[0] == 0)
{
return c;
}
if (strequal(usr_creds->ntc.domain, c->cli->usr.ntc.domain))
{
return c;
}
}
return NULL;
}
/****************************************************************************
create a new client state from user credentials
****************************************************************************/
static struct msrpc_use *msrpc_use_get(const char* pipe_name,
const struct user_creds *usr_creds)
{
struct msrpc_use *cli = (struct msrpc_use*)malloc(sizeof(*cli));
if (cli == NULL)
{
return NULL;
}
memset(cli, 0, sizeof(*cli));
cli->cli = msrpc_initialise(NULL);
if (cli->cli == NULL)
{
return NULL;
}
msrpc_init_creds(cli->cli, usr_creds);
return cli;
}
/****************************************************************************
init client state
****************************************************************************/
struct msrpc_state *msrpc_use_add(const char* pipe_name,
const struct user_creds *usr_creds,
BOOL redir)
{
struct msrpc_use *cli;
DEBUG(10,("msrpc_use_add: %s redir: %s\n", pipe_name, BOOLSTR(redir)));
cli = msrpc_find(pipe_name, usr_creds);
if (cli != NULL)
{
cli->num_users++;
return cli->cli;
}
/* reuse an existing connection requested, and one was not found */
if (usr_creds != NULL && usr_creds->reuse && !redir)
{
DEBUG(0,("msrpc_use_add: reuse requested, but one not found\n"));
return False;
}
/*
* allocate
*/
cli = msrpc_use_get(pipe_name, usr_creds);
cli->cli->redirect = redir;
if (!msrpc_establish_connection(cli->cli, pipe_name))
{
DEBUG(0,("msrpc_use_add: connection failed\n"));
cli->cli = NULL;
msrpc_use_free(cli);
return NULL;
}
add_msrpc_to_array(&num_msrpcs, &msrpcs, cli);
cli->num_users++;
return cli->cli;
}
/****************************************************************************
delete a client state
****************************************************************************/
BOOL msrpc_use_del(const char* pipe_name,
const struct user_creds *usr_creds,
BOOL force_close,
BOOL *connection_closed)
{
int i;
DEBUG(10,("msrpc_net_use_del: %s. force close: %s\n",
pipe_name, BOOLSTR(force_close)));
if (connection_closed != NULL)
{
*connection_closed = False;
}
for (i = 0; i < num_msrpcs; i++)
{
char *msrpc_name = NULL;
if (msrpcs[i] == NULL) continue;
if (msrpcs[i]->cli == NULL) continue;
msrpc_name = msrpcs[i]->cli->pipe_name;
if (!strequal(msrpc_name, pipe_name)) continue;
if (strequal(usr_creds->ntc.user_name,
msrpcs[i]->cli->usr.ntc.user_name) &&
strequal(usr_creds->ntc.domain,
msrpcs[i]->cli->usr.ntc.domain))
{
/* decrement number of users */
msrpcs[i]->num_users--;
DEBUG(10,("idx: %i num_users now: %d\n",
i, msrpcs[i]->num_users));
if (force_close || msrpcs[i]->num_users == 0)
{
msrpc_use_free(msrpcs[i]);
msrpcs[i] = NULL;
if (connection_closed != NULL)
{
*connection_closed = True;
}
}
return True;
}
}
return False;
}
/****************************************************************************
enumerate client states
****************************************************************************/
void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use)
{
int i;
*num_cons = 0;
*use = NULL;
for (i = 0; i < num_msrpcs; i++)
{
struct use_info item;
ZERO_STRUCT(item);
if (msrpcs[i] == NULL) continue;
item.connected = msrpcs[i]->cli != NULL ? True : False;
if (item.connected)
{
item.srv_name = msrpcs[i]->cli->pipe_name;
item.user_name = msrpcs[i]->cli->usr.ntc.user_name;
item.domain = msrpcs[i]->cli->usr.ntc.domain;
}
add_use_info_to_array(num_cons, use, &item);
}
}

View File

@ -357,6 +357,21 @@ BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
return(S_ISREG(sbuf->st_mode));
}
/*******************************************************************
rename a unix file
********************************************************************/
int file_rename(char *from, char *to)
{
int rcode = rename (from, to);
if (errno == EXDEV)
{
/* Rename across filesystems needed. */
rcode = copy_reg (from, to);
}
return rcode;
}
/*******************************************************************
check a files mod time
********************************************************************/

194
source3/lib/util_array.c Normal file
View File

@ -0,0 +1,194 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1999
Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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.
*/
#include "includes.h"
void free_void_array(uint32 num_entries, void **entries,
void(free_item)(void*))
{
uint32 i;
if (entries != NULL)
{
for (i = 0; i < num_entries; i++)
{
if (entries[i] != NULL)
{
free_item(entries[i]);
}
}
free(entries);
}
}
void* add_copy_to_array(uint32 *len, void ***array, const void *item,
void*(item_dup)(const void*), BOOL alloc_anyway)
{
void* copy = NULL;
if (len == NULL || array == NULL)
{
return NULL;
}
if (item != NULL || alloc_anyway)
{
copy = item_dup(item);
return add_item_to_array(len, array, copy);
}
return copy;
}
void* add_item_to_array(uint32 *len, void ***array, void *item)
{
if (len == NULL || array == NULL)
{
return NULL;
}
(*array) = (void**)Realloc((*array), ((*len)+1)*sizeof((*array)[0]));
if ((*array) != NULL)
{
(*array)[(*len)] = item;
(*len)++;
return item;
}
return NULL;
}
static void use_info_free(struct use_info *item)
{
if (item != NULL)
{
if (item->srv_name != NULL)
{
free(item->srv_name);
}
if (item->user_name != NULL)
{
free(item->user_name);
}
if (item->domain != NULL)
{
free(item->domain);
}
free(item);
}
}
static struct use_info *use_info_dup(const struct use_info *from)
{
if (from != NULL)
{
struct use_info *copy = (struct use_info *)
malloc(sizeof(struct use_info));
if (copy != NULL)
{
ZERO_STRUCTP(copy);
copy->connected = from->connected;
if (from->srv_name != NULL)
{
copy->srv_name = strdup(from->srv_name );
}
if (from->user_name != NULL)
{
copy->user_name = strdup(from->user_name);
}
if (from->domain != NULL)
{
copy->domain = strdup(from->domain );
}
}
return copy;
}
return NULL;
}
void free_use_info_array(uint32 num_entries, struct use_info **entries)
{
void(*fn)(void*) = (void(*)(void*))&use_info_free;
free_void_array(num_entries, (void**)entries, *fn);
}
struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array,
const struct use_info *name)
{
void*(*fn)(const void*) = (void*(*)(const void*))&use_info_dup;
return (struct use_info*)add_copy_to_array(len,
(void***)array, (const void*)name, *fn, False);
}
void free_char_array(uint32 num_entries, char **entries)
{
void(*fn)(void*) = (void(*)(void*))&free;
free_void_array(num_entries, (void**)entries, *fn);
}
char* add_chars_to_array(uint32 *len, char ***array, const char *name)
{
void*(*fn)(const void*) = (void*(*)(const void*))&strdup;
return (char*)add_copy_to_array(len,
(void***)array, (const void*)name, *fn, False);
}
static uint32 *uint32_dup(const uint32* from)
{
if (from != NULL)
{
uint32 *copy = (uint32 *)malloc(sizeof(uint32));
if (copy != NULL)
{
memcpy(copy, from, sizeof(*copy));
}
return copy;
}
return NULL;
}
void free_uint32_array(uint32 num_entries, uint32 **entries)
{
void(*fn)(void*) = (void(*)(void*))&free;
free_void_array(num_entries, (void**)entries, *fn);
}
uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name)
{
void*(*fn)(const void*) = (void*(*)(const void*))&uint32_dup;
return (uint32*)add_copy_to_array(len,
(void***)array, (const void*)name, *fn, False);
}
void free_sid_array(uint32 num_entries, DOM_SID **entries)
{
void(*fn)(void*) = (void(*)(void*))&free;
free_void_array(num_entries, (void**)entries, *fn);
}
DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid)
{
void*(*fn)(const void*) = (void*(*)(const void*))&sid_dup;
return (DOM_SID*)add_copy_to_array(len,
(void***)array, (const void*)sid, *fn, False);
}

View File

@ -335,7 +335,7 @@ BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
Copies a sid
*****************************************************************/
void sid_copy(DOM_SID *dst, DOM_SID *src)
void sid_copy(DOM_SID *dst, const DOM_SID *src)
{
int i;
@ -424,3 +424,291 @@ size_t sid_size(DOM_SID *sid)
return sid->num_auths * sizeof(uint32) + 8;
}
static BOOL read_sid_from_file(int fd, char *sid_file, DOM_SID *sid)
{
fstring fline;
fstring sid_str;
memset(fline, '\0', sizeof(fline));
if (read(fd, fline, sizeof(fline) -1 ) < 0) {
DEBUG(0,("unable to read file %s. Error was %s\n",
sid_file, strerror(errno) ));
return False;
}
/*
* Convert to the machine SID.
*/
fline[sizeof(fline)-1] = '\0';
if (!string_to_sid(sid, fline)) {
DEBUG(0,("unable to read sid.\n"));
return False;
}
sid_to_string(sid_str, sid);
DEBUG(5,("read_sid_from_file: sid %s\n", sid_str));
return True;
}
/****************************************************************************
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
BOOL read_sid(char *sam_name, DOM_SID *sid)
{
int fd;
char *p;
pstring sid_file;
fstring file_name;
SMB_STRUCT_STAT st;
pstrcpy(sid_file, lp_smb_passwd_file());
DEBUG(10,("read_sid: Domain: %s\n", sam_name));
if (sid_file[0] == 0)
{
DEBUG(0,("cannot find smb passwd file\n"));
return False;
}
p = strrchr(sid_file, '/');
if (p != NULL)
{
*++p = '\0';
}
if (!directory_exist(sid_file, NULL))
{
if (mkdir(sid_file, 0700) != 0)
{
DEBUG(0,("can't create private directory %s : %s\n",
sid_file, strerror(errno)));
return False;
}
}
slprintf(file_name, sizeof(file_name)-1, "%s.SID", sam_name);
strupper(file_name);
pstrcat(sid_file, file_name);
if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
DEBUG(0,("unable to open or create file %s. Error was %s\n",
sid_file, strerror(errno) ));
return False;
}
/*
* Check if the file contains data.
*/
if (sys_fstat(fd, &st) < 0) {
DEBUG(0,("unable to stat file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
if (st.st_size == 0)
{
close(fd);
return False;
}
/*
* We have a valid SID - read it.
*/
if (!read_sid_from_file(fd, sid_file, sid))
{
DEBUG(0,("unable to read file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
close(fd);
return True;
}
/****************************************************************************
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
BOOL write_sid(char *sam_name, DOM_SID *sid)
{
int fd;
char *p;
pstring sid_file;
fstring sid_string;
fstring file_name;
SMB_STRUCT_STAT st;
pstrcpy(sid_file, lp_smb_passwd_file());
sid_to_string(sid_string, sid);
DEBUG(10,("write_sid: Domain: %s SID: %s\n", sam_name, sid_string));
fstrcat(sid_string, "\n");
if (sid_file[0] == 0)
{
DEBUG(0,("cannot find smb passwd file\n"));
return False;
}
p = strrchr(sid_file, '/');
if (p != NULL)
{
*++p = '\0';
}
if (!directory_exist(sid_file, NULL)) {
if (mkdir(sid_file, 0700) != 0) {
DEBUG(0,("can't create private directory %s : %s\n",
sid_file, strerror(errno)));
return False;
}
}
slprintf(file_name, sizeof(file_name)-1, "%s.SID", sam_name);
strupper(file_name);
pstrcat(sid_file, file_name);
if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
DEBUG(0,("unable to open or create file %s. Error was %s\n",
sid_file, strerror(errno) ));
return False;
}
/*
* Check if the file contains data.
*/
if (sys_fstat(fd, &st) < 0) {
DEBUG(0,("unable to stat file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
if (st.st_size > 0)
{
/*
* We have a valid SID already.
*/
close(fd);
DEBUG(0,("SID file %s already exists\n", sid_file));
return False;
}
if (!do_file_lock(fd, 60, F_WRLCK))
{
DEBUG(0,("unable to lock file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
/*
* At this point we have a blocking lock on the SID
* file - check if in the meantime someone else wrote
* SID data into the file. If so - they were here first,
* use their data.
*/
if (sys_fstat(fd, &st) < 0)
{
DEBUG(0,("unable to stat file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
if (st.st_size > 0)
{
/*
* Unlock as soon as possible to reduce
* contention on the exclusive lock.
*/
do_file_lock(fd, 60, F_UNLCK);
/*
* We have a valid SID already.
*/
DEBUG(0,("SID file %s already exists\n", sid_file));
close(fd);
return False;
}
/*
* The file is still empty and we have an exlusive lock on it.
* Write out out SID data into the file.
*/
if (fchmod(fd, 0644) < 0)
{
DEBUG(0,("unable to set correct permissions on file %s. \
Error was %s\n", sid_file, strerror(errno) ));
close(fd);
return False;
}
if (write(fd, sid_string, strlen(sid_string)) != strlen(sid_string))
{
DEBUG(0,("unable to write file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
/*
* Unlock & exit.
*/
do_file_lock(fd, 60, F_UNLCK);
close(fd);
return True;
}
/****************************************************************************
create a random SID.
****************************************************************************/
BOOL create_new_sid(DOM_SID *sid)
{
uchar raw_sid_data[12];
fstring sid_string;
int i;
/*
* Generate the new sid data & turn it into a string.
*/
generate_random_buffer(raw_sid_data, 12, True);
fstrcpy(sid_string, "S-1-5-21");
for(i = 0; i < 3; i++)
{
fstring tmp_string;
slprintf(tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
fstrcat(sid_string, tmp_string);
}
fstrcat(sid_string, "\n");
/*
* Ensure our new SID is valid.
*/
if (!string_to_sid(sid, sid_string))
{
DEBUG(0,("unable to generate machine SID.\n"));
return False;
}
return True;
}

View File

@ -1041,3 +1041,103 @@ char *client_addr(int fd)
global_client_addr_done = True;
return addr_buf;
}
/*******************************************************************
opens and connects to a unix pipe socket
******************************************************************/
int open_pipe_sock(char *path)
{
int sock;
struct sockaddr_un sa;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
{
DEBUG(0, ("unix socket open failed\n"));
return sock;
}
ZERO_STRUCT(sa);
sa.sun_family = AF_UNIX;
safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path));
if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
{
DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
close(sock);
return -1;
}
return sock;
}
int create_pipe_socket(char *dir, int dir_perms,
char *path, int path_perms)
{
int s;
struct sockaddr_un sa;
DEBUG(0,("create_pipe_socket: %s %d %s %d\n",
dir, dir_perms, path, path_perms));
DEBUG(0,("*** RACE CONDITION. PLEASE SOMEONE EXAMINE create_pipe_Socket AND FIX IT ***\n"));
mkdir(dir, dir_perms);
if (chmod(dir, dir_perms) < 0)
{
DEBUG(0, ("chmod on %s failed\n", dir));
return -1;
}
if (!remove(path))
{
DEBUG(0, ("remove on %s failed\n", path));
}
/* start listening on unix socket */
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s < 0)
{
DEBUG(0, ("socket open failed\n"));
return -1;
}
ZERO_STRUCT(sa);
sa.sun_family = AF_UNIX;
safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0)
{
DEBUG(0, ("socket bind to %s failed\n", sa.sun_path));
close(s);
remove(path);
return -1;
}
if (s == -1)
{
DEBUG(0,("bind failed\n"));
remove(path);
return -1;
}
if (path_perms != 0)
{
chmod(path, path_perms);
}
if (listen(s, 5) == -1)
{
DEBUG(0,("listen failed\n"));
return -1;
}
DEBUG(5,("unix socket opened: %s\n", path));
return s;
}

View File

@ -61,6 +61,60 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key)
{
}
/****************************************************************************
compares two passwords. hmm, not as trivial as expected. hmm.
****************************************************************************/
BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
{
pwd_deobfuscate(pwd1);
pwd_deobfuscate(pwd2);
if (pwd1->cleartext && pwd2->cleartext)
{
if (strequal(pwd1->password, pwd2->password))
{
pwd_obfuscate(pwd1);
pwd_obfuscate(pwd2);
return True;
}
}
if (pwd1->null_pwd && pwd2->null_pwd)
{
pwd_obfuscate(pwd1);
pwd_obfuscate(pwd2);
return True;
}
if (!pwd1->null_pwd && !pwd2->null_pwd &&
!pwd1->cleartext && !pwd2->cleartext)
{
#ifdef DEBUG_PASSWORD
DEBUG(100,("pwd compare: nt#\n"));
dump_data(100, pwd1->smb_nt_pwd, 16);
dump_data(100, pwd2->smb_nt_pwd, 16);
#endif
if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
{
pwd_obfuscate(pwd1);
pwd_obfuscate(pwd2);
return True;
}
#ifdef DEBUG_PASSWORD
DEBUG(100,("pwd compare: lm#\n"));
dump_data(100, pwd1->smb_lm_pwd, 16);
dump_data(100, pwd2->smb_lm_pwd, 16);
#endif
if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
{
pwd_obfuscate(pwd1);
pwd_obfuscate(pwd2);
return True;
}
}
pwd_obfuscate(pwd1);
pwd_obfuscate(pwd2);
return False;
}
/****************************************************************************
reads a password
****************************************************************************/

View File

@ -788,52 +788,32 @@ BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
}
/****************************************************************************
Read the machine SID from a file.
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
static BOOL read_sid_from_file(int fd, char *sid_file)
{
fstring fline;
memset(fline, '\0', sizeof(fline));
if(read(fd, fline, sizeof(fline) -1 ) < 0) {
DEBUG(0,("unable to read file %s. Error was %s\n",
sid_file, strerror(errno) ));
return False;
}
/*
* Convert to the machine SID.
*/
fline[sizeof(fline)-1] = '\0';
if(!string_to_sid( &global_sam_sid, fline)) {
DEBUG(0,("unable to generate machine SID.\n"));
return False;
}
return True;
}
/****************************************************************************
Generate the global machine sid. Look for the MACHINE.SID file first, if
not found then look in smb.conf and use it to create the MACHINE.SID file.
****************************************************************************/
BOOL pdb_generate_sam_sid(void)
BOOL pdb_generate_sam_sid(char *domain_name, DOM_SID *sid)
{
int fd;
char *p;
pstring sid_file;
fstring sid_string;
SMB_STRUCT_STAT st;
BOOL overwrite_bad_sid = False;
pstring machine_sid_file;
fstring file_name;
generate_wellknown_sids();
if (sid == NULL)
{
sid = &global_sam_sid;
}
pstrcpy(sid_file, lp_smb_passwd_file());
if (sid_file[0] == 0)
{
DEBUG(0,("cannot find smb passwd file\n"));
return False;
}
p = strrchr(sid_file, '/');
if(p != NULL) {
if (p != NULL)
{
*++p = '\0';
}
@ -845,180 +825,55 @@ BOOL pdb_generate_sam_sid(void)
}
}
pstrcat(sid_file, "MACHINE.SID");
pstrcpy(machine_sid_file, sid_file);
pstrcat(machine_sid_file, "MACHINE.SID");
slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
strupper(file_name);
pstrcat(sid_file, file_name);
if((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
DEBUG(0,("unable to open or create file %s. Error was %s\n",
sid_file, strerror(errno) ));
return False;
}
/*
* Check if the file contains data.
*/
if(sys_fstat( fd, &st) < 0) {
DEBUG(0,("unable to stat file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
if(st.st_size > 0) {
/*
* We have a valid SID - read it.
*/
if(!read_sid_from_file( fd, sid_file)) {
DEBUG(0,("unable to read file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
if (file_exist(machine_sid_file, NULL))
{
if (file_exist(sid_file, NULL))
{
DEBUG(0,("both %s and %s exist when only one should, unable to continue\n",
machine_sid_file, sid_file));
return False;
}
/*
* JRA. Reversed the sense of this test now that I have
* actually done this test *personally*. One more reason
* to never trust third party information you have not
* independently verified.... sigh. JRA.
*/
if(global_sam_sid.num_auths > 0 && global_sam_sid.sub_auths[0] == 0x21) {
/*
* Fix and re-write...
*/
overwrite_bad_sid = True;
global_sam_sid.sub_auths[0] = 21;
DEBUG(5,("pdb_generate_sam_sid: Old (incorrect) sid id_auth of hex 21 \
detected - re-writing to be decimal 21 instead.\n" ));
sid_to_string(sid_string, &global_sam_sid);
if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0) {
DEBUG(0,("unable to seek file file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
} else {
close(fd);
return True;
}
} else {
/*
* The file contains no data - we need to generate our
* own sid.
* Generate the new sid data & turn it into a string.
*/
int i;
uchar raw_sid_data[12];
DOM_SID mysid;
memset((char *)&mysid, '\0', sizeof(DOM_SID));
mysid.sid_rev_num = 1;
mysid.id_auth[5] = 5;
mysid.num_auths = 0;
mysid.sub_auths[mysid.num_auths++] = 21;
generate_random_buffer( raw_sid_data, 12, True);
for( i = 0; i < 3; i++)
mysid.sub_auths[mysid.num_auths++] = IVAL(raw_sid_data, i*4);
sid_to_string(sid_string, &mysid);
}
fstrcat(sid_string, "\n");
/*
* Ensure our new SID is valid.
*/
if(!string_to_sid( &global_sam_sid, sid_string)) {
DEBUG(0,("unable to generate machine SID.\n"));
return False;
}
/*
* Do an exclusive blocking lock on the file.
*/
if(!do_file_lock( fd, 60, F_WRLCK)) {
DEBUG(0,("unable to lock file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
if(!overwrite_bad_sid) {
/*
* At this point we have a blocking lock on the SID
* file - check if in the meantime someone else wrote
* SID data into the file. If so - they were here first,
* use their data.
*/
if(sys_fstat( fd, &st) < 0) {
DEBUG(0,("unable to stat file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
if (file_rename(machine_sid_file, sid_file))
{
DEBUG(0,("could not rename %s to %s. Error was %s\n",
machine_sid_file, sid_file, strerror(errno)));
return False;
}
if(st.st_size > 0) {
/*
* Unlock as soon as possible to reduce
* contention on the exclusive lock.
*/
do_file_lock( fd, 60, F_UNLCK);
/*
* We have a valid SID - read it.
*/
if(!read_sid_from_file( fd, sid_file)) {
DEBUG(0,("unable to read file %s. Error was %s\n",
sid_file, strerror(errno) ));
close(fd);
return False;
}
close(fd);
return True;
}
}
}
/*
* The file is still empty and we have an exlusive lock on it,
* or we're fixing an earlier mistake.
* Write out out SID data into the file.
*/
/*
* Use chmod here as some (strange) UNIX's don't
* have fchmod. JRA.
*/
if(chmod(sid_file, 0644) < 0) {
DEBUG(0,("unable to set correct permissions on file %s. \
Error was %s\n", sid_file, strerror(errno) ));
do_file_lock( fd, 60, F_UNLCK);
close(fd);
/* attempt to read the SID from the file */
if (read_sid(domain_name, sid))
{
return True;
}
if (!create_new_sid(sid))
{
return False;
}
if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
DEBUG(0,("unable to write file %s. Error was %s\n",
sid_file, strerror(errno) ));
do_file_lock( fd, 60, F_UNLCK);
close(fd);
return False;
}
/*
* Unlock & exit.
*/
do_file_lock( fd, 60, F_UNLCK);
close(fd);
}
/* attempt to read the SID from the file */
if (!write_sid(domain_name, sid))
{
return True;
}
/* during the attempt to write, someone else wrote? */
/* attempt to read the SID from the file */
if (read_sid(domain_name, sid))
{
return True;
}
return True;
}
/*******************************************************************
Converts NT user RID to a UNIX uid.
********************************************************************/

View File

@ -0,0 +1,578 @@
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tgrpsgell 1992-1999,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
* Copyright (C) Paul Ashton 1997-1999.
*
* 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, Cambgrpsge, MA 02139, USA.
*/
#include "includes.h"
extern int DEBUGLEVEL;
/*******************************************************************
makes a CREDS_UNIX structure.
********************************************************************/
BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
const char* requested_name,
const char* real_name,
BOOL guest)
{
if (r_u == NULL) return False;
DEBUG(5,("make_creds_unix\n"));
fstrcpy(r_u->user_name , user_name);
fstrcpy(r_u->requested_name, requested_name);
fstrcpy(r_u->real_name , real_name);
r_u->guest = guest;
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "creds_io_unix");
depth++;
prs_align(ps);
prs_string("user_name", ps, depth, r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
prs_align(ps);
prs_string("requested_name", ps, depth, r_u->requested_name, strlen(r_u->requested_name), sizeof(r_u->requested_name));
prs_align(ps);
prs_string("real_name", ps, depth, r_u->real_name, strlen(r_u->real_name), sizeof(r_u->real_name));
prs_align(ps);
prs_uint32("guest", ps, depth, &(r_u->guest));
return True;
}
/*******************************************************************
frees a structure.
********************************************************************/
void creds_free_unix(CREDS_UNIX *r_u)
{
}
/*******************************************************************
makes a CREDS_UNIX_SEC structure.
********************************************************************/
BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps)
{
int i;
if (r_u == NULL) return False;
DEBUG(5,("make_creds_unix_sec\n"));
r_u->uid = uid;
r_u->gid = gid;
r_u->num_grps = num_grps;
r_u->grps = (uint32*)Realloc(NULL, sizeof(r_u->grps[0]) *
r_u->num_grps);
if (r_u->grps == NULL && num_grps != 0)
{
return False;
}
for (i = 0; i < num_grps; i++)
{
r_u->grps[i] = (gid_t)grps[i];
}
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth)
{
uint32 i;
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "creds_io_unix_sec");
depth++;
prs_align(ps);
prs_uint32("uid", ps, depth, &(r_u->uid));
prs_uint32("gid", ps, depth, &(r_u->gid));
prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
if (r_u->num_grps != 0)
{
r_u->grps = (uint32*)Realloc(r_u->grps,
sizeof(r_u->grps[0]) *
r_u->num_grps);
if (r_u->grps == NULL)
{
creds_free_unix_sec(r_u);
return False;
}
}
for (i = 0; i < r_u->num_grps; i++)
{
prs_uint32("", ps, depth, &(r_u->grps[i]));
}
return True;
}
/*******************************************************************
frees a structure.
********************************************************************/
void creds_free_unix_sec(CREDS_UNIX_SEC *r_u)
{
if (r_u->grps != NULL)
{
free(r_u->grps);
r_u->grps = NULL;
}
}
/*******************************************************************
makes a CREDS_NT_SEC structure.
********************************************************************/
BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
DOM_SID *sid, uint32 num_grps, uint32 *grps)
{
int i;
if (r_u == NULL) return False;
DEBUG(5,("make_creds_unix_sec\n"));
sid_copy(&r_u->sid, sid);
r_u->num_grps = num_grps;
r_u->grp_rids = (uint32*)Realloc(NULL, sizeof(r_u->grp_rids[0]) *
r_u->num_grps);
if (r_u->grp_rids == NULL && num_grps != 0)
{
return False;
}
for (i = 0; i < num_grps; i++)
{
r_u->grp_rids[i] = grps[i];
}
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth)
{
int i;
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "creds_io_nt");
depth++;
prs_align(ps);
smb_io_dom_sid ("sid", &r_u->sid, ps, depth);
prs_align(ps);
prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
if (r_u->num_grps != 0)
{
r_u->grp_rids = (uint32*)Realloc(r_u->grp_rids,
sizeof(r_u->grp_rids[0]) *
r_u->num_grps);
if (r_u->grp_rids == NULL)
{
creds_free_nt_sec(r_u);
return False;
}
}
for (i = 0; i < r_u->num_grps; i++)
{
prs_uint32("", ps, depth, &(r_u->grp_rids[i]));
}
return True;
}
/*******************************************************************
frees a structure.
********************************************************************/
void creds_free_nt_sec(CREDS_NT_SEC *r_u)
{
if (r_u->grp_rids != NULL)
{
free(r_u->grp_rids);
r_u->grp_rids = NULL;
}
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth)
{
if (pwd == NULL) return False;
prs_debug(ps, depth, desc, "creds_io_pwd_info");
depth++;
prs_align(ps);
prs_uint32("nullpwd", ps, depth, &(pwd->null_pwd));
if (pwd->null_pwd)
{
return True;
}
prs_uint32("cleartext", ps, depth, &(pwd->cleartext));
if (pwd->cleartext)
{
prs_string("password", ps, depth, pwd->password, strlen(pwd->password), sizeof(pwd->password));
prs_align(ps);
return True;
}
prs_uint32("crypted", ps, depth, &(pwd->crypted));
prs_uint8s(False, "smb_lm_pwd", ps, depth, (char*)&pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
prs_align(ps);
prs_uint8s(False, "smb_nt_pwd", ps, depth, (char*)&pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
prs_align(ps);
prs_uint8s(False, "smb_lm_owf", ps, depth, (char*)&pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
prs_align(ps);
prs_uint32("nt_owf_len", ps, depth, &(pwd->nt_owf_len));
if (pwd->nt_owf_len > sizeof(pwd->smb_nt_owf))
{
return False;
}
prs_uint8s(False, "smb_nt_owf", ps, depth, (char*)&pwd->smb_nt_owf, pwd->nt_owf_len);
prs_align(ps);
prs_uint8s(False, "lm_cli_chal", ps, depth, (char*)&pwd->lm_cli_chal, sizeof(pwd->lm_cli_chal));
prs_align(ps);
prs_uint32("nt_cli_chal_len", ps, depth, &(pwd->nt_cli_chal_len));
if (pwd->nt_cli_chal_len > sizeof(pwd->nt_cli_chal))
{
return False;
}
prs_uint8s(False, "nt_cli_chal", ps, depth, (char*)&pwd->nt_cli_chal, pwd->nt_cli_chal_len);
prs_align(ps);
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "creds_io_nt");
depth++;
prs_align(ps);
/* lkclXXXX CHEAT!!!!!!!! */
prs_string("user_name", ps, depth, r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
prs_align(ps);
prs_string("domain", ps, depth, r_u->domain, strlen(r_u->domain), sizeof(r_u->domain));
prs_align(ps);
creds_io_pwd_info("pwd", &r_u->pwd, ps, depth);
prs_align(ps);
prs_uint32("ntlmssp", ps, depth, &(r_u->ntlmssp_flags));
return True;
}
/*******************************************************************
frees a structure.
********************************************************************/
void creds_free_nt(CREDS_NT *r_u)
{
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "creds_io_hybrid");
depth++;
prs_align(ps);
prs_uint32("reuse", ps, depth, &(r_u->reuse));
prs_uint32("ptr_ntc", ps, depth, &(r_u->ptr_ntc));
prs_uint32("ptr_uxc", ps, depth, &(r_u->ptr_uxc));
prs_uint32("ptr_nts", ps, depth, &(r_u->ptr_nts));
prs_uint32("ptr_uxs", ps, depth, &(r_u->ptr_uxs));
if (r_u->ptr_ntc != 0)
{
if (!creds_io_nt ("ntc", &r_u->ntc, ps, depth)) return False;
}
if (r_u->ptr_uxc != 0)
{
if (!creds_io_unix("uxc", &r_u->uxc, ps, depth)) return False;
}
if (r_u->ptr_nts != 0)
{
if (!creds_io_nt_sec ("nts", &r_u->nts, ps, depth)) return False;
}
if (r_u->ptr_uxs != 0)
{
if (!creds_io_unix_sec("uxs", &r_u->uxs, ps, depth)) return False;
}
return True;
}
void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from)
{
if (from == NULL)
{
to->user_name[0] = 0;
return;
}
fstrcpy(to->user_name, from->user_name);
};
void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from)
{
if (from == NULL)
{
ZERO_STRUCTP(to);
return;
}
sid_copy(&to->sid, &from->sid);
to->num_grps = 0;
to->grp_rids = NULL;
if (from->num_grps != 0)
{
size_t size = from->num_grps * sizeof(from->grp_rids[0]);
to->grp_rids = (uint32*)malloc(size);
if (to->grp_rids == NULL)
{
return;
}
to->num_grps = from->num_grps;
memcpy(to->grp_rids, from->grp_rids, size);
}
};
void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
{
if (from == NULL)
{
to->uid = -1;
to->gid = -1;
to->num_grps = 0;
to->grps = NULL;
return;
}
to->uid = from->uid;
to->gid = from->gid;
to->num_grps = 0;
to->grps = NULL;
if (from->num_grps != 0)
{
size_t size = from->num_grps * sizeof(from->grps[0]);
to->grps = (uint32*)malloc(size);
if (to->grps == NULL)
{
return;
}
to->num_grps = from->num_grps;
memcpy(to->grps, from->grps, size);
}
};
void copy_nt_creds(struct ntuser_creds *to,
const struct ntuser_creds *from)
{
if (from == NULL)
{
DEBUG(10,("copy_nt_creds: null creds\n"));
to->domain[0] = 0;
to->user_name[0] = 0;
pwd_set_nullpwd(&to->pwd);
to->ntlmssp_flags = 0;
return;
}
safe_strcpy(to->domain , from->domain , sizeof(from->domain )-1);
safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
to->ntlmssp_flags = from->ntlmssp_flags;
};
void copy_user_creds(struct user_creds *to,
const struct user_creds *from)
{
ZERO_STRUCTP(to);
if (from == NULL)
{
to->ptr_ntc = 0;
to->ptr_uxc = 0;
to->ptr_nts = 0;
to->ptr_uxs = 0;
copy_nt_creds(&to->ntc, NULL);
copy_unix_creds(&to->uxc, NULL);
copy_nt_sec_creds(&to->nts, NULL);
copy_unix_sec_creds(&to->uxs, NULL);
to->reuse = False;
return;
}
to->ptr_nts = from->ptr_nts;
to->ptr_uxs = from->ptr_uxs;
to->ptr_ntc = from->ptr_ntc;
to->ptr_uxc = from->ptr_uxc;
if (to->ptr_ntc != 0)
{
copy_nt_creds(&to->ntc, &from->ntc);
}
if (to->ptr_uxc != 0)
{
copy_unix_creds(&to->uxc, &from->uxc);
}
if (to->ptr_nts != 0)
{
copy_nt_sec_creds(&to->nts, &from->nts);
}
if (to->ptr_uxs != 0)
{
copy_unix_sec_creds(&to->uxs, &from->uxs);
}
to->reuse = from->reuse;
};
void free_user_creds(struct user_creds *creds)
{
creds_free_unix(&creds->uxc);
creds_free_nt (&creds->ntc);
creds_free_unix_sec(&creds->uxs);
creds_free_nt_sec (&creds->nts);
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "creds_io_cmd");
depth++;
prs_align(ps);
prs_uint16("version", ps, depth, &(r_u->version));
prs_uint16("command", ps, depth, &(r_u->command));
prs_string("name ", ps, depth, r_u->name, strlen(r_u->name), sizeof(r_u->name));
prs_align(ps);
prs_uint32("ptr_creds", ps, depth, &(r_u->ptr_creds));
if (r_u->ptr_creds != 0)
{
if (!creds_io_hybrid("creds", r_u->cred, ps, depth))
{
return False;
}
}
return True;
}
BOOL create_ntuser_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
const struct ntuser_creds *ntu,
BOOL reuse)
{
CREDS_CMD cmd;
struct user_creds usr;
ZERO_STRUCT(cmd);
ZERO_STRUCT(usr);
DEBUG(10,("create_user_creds: %s %d %d\n",
name, version, command));
usr.reuse = reuse;
fstrcpy(cmd.name, name);
cmd.version = version;
cmd.command = command;
cmd.ptr_creds = ntu != NULL ? 1 : 0;
cmd.cred = &usr;
if (ntu != NULL)
{
copy_nt_creds(&usr.ntc, ntu);
usr.ptr_ntc = 1;
}
else
{
usr.ptr_ntc = 0;
}
prs_init(ps, 1024, 4, False);
ps->data_offset = 4;
return creds_io_cmd("creds", &cmd, ps, 0);
}
BOOL create_user_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
const struct user_creds *usr)
{
CREDS_CMD cmd;
ZERO_STRUCT(cmd);
DEBUG(10,("create_user_creds: %s %d %d\n",
name, version, command));
fstrcpy(cmd.name, name);
cmd.version = version;
cmd.command = command;
cmd.ptr_creds = usr != NULL ? 1 : 0;
cmd.cred = usr;
prs_init(ps, 1024, 4, False);
ps->data_offset = 4;
return creds_io_cmd("creds", &cmd, ps, 0);
}

View File

@ -64,6 +64,30 @@ BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io)
return True;
}
/*******************************************************************
read from a socket into memory.
********************************************************************/
BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout)
{
BOOL ok;
size_t prev_size = ps->buffer_size;
if (!prs_grow(ps, len))
{
return False;
}
if (timeout > 0)
{
ok = (read_with_timeout(fd, &ps->data_p[prev_size],
len, len,timeout) == len);
}
else
{
ok = (read_data(fd, &ps->data_p[prev_size], len) == len);
}
return ok;
}
/*******************************************************************
Delete the memory in a parse structure - if we own it.
********************************************************************/

File diff suppressed because it is too large Load Diff

View File

@ -113,10 +113,44 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
int i;
pipes_struct *p;
static int next_pipe;
struct msrpc_state *m = NULL;
user_struct *vuser = get_valid_user_struct(vuid);
struct user_creds usr;
ZERO_STRUCT(usr);
DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
pipe_name, pipes_open));
if (vuser == NULL)
{
DEBUG(4,("invalid vuid %d\n", vuid));
return NULL;
}
/* set up unix credentials from the smb side, to feed over the pipe */
make_creds_unix(&usr.uxc, vuser->name, vuser->requested_name,
vuser->real_name, vuser->guest);
usr.ptr_uxc = 1;
make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
vuser->n_groups, vuser->groups);
usr.ptr_uxs = 1;
/* set up nt credentials from the smb side, to feed over the pipe */
/* lkclXXXX todo!
make_creds_nt(&usr.ntc);
make_creds_nt_sec(&usr.nts);
*/
become_root(False); /* to connect to pipe */
m = msrpc_use_add(pipe_name, &usr, False);
unbecome_root(False);
if (m == NULL)
{
DEBUG(10,("open pipes: msrpc redirect failed - go local.\n"));
}
/* not repeating pipe numbers makes it easier to track things in
log files and prevents client bugs where pipe numbers are reused
over connection restarts */
@ -160,6 +194,8 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
p->priority = 0;
p->conn = conn;
p->vuid = vuid;
p->m = m;
p->max_trans_reply = 0;
@ -201,7 +237,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
{
DEBUG(6,("write_pipe: %x", p->pnum));
DEBUG(6,("write_to_pipe: %x", p->pnum));
DEBUG(6,("name: %s open: %s len: %d",
p->name, BOOLSTR(p->open), (int)n));
@ -372,6 +408,19 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
p->name, p->pnum, pipes_open));
if (p->m != NULL)
{
DEBUG(4,("closed msrpc redirect: "));
if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
{
DEBUG(4,("OK\n"));
}
else
{
DEBUG(4,("FAILED\n"));
}
}
DLIST_REMOVE(Pipes, p);
ZERO_STRUCTP(p);

File diff suppressed because it is too large Load Diff

View File

@ -3154,11 +3154,20 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
Start the first part of an RPC reply which began with an SMBtrans request.
****************************************************************************/
static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p)
static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p,
char *redir_data, int redir_len)
{
char *rdata = malloc(p->max_trans_reply);
char *rdata;
int data_len;
if (redir_data != NULL)
{
send_trans_reply(outbuf, NULL, 0, redir_data, redir_len,
redir_len > p->max_trans_reply);
return True;
}
rdata = malloc(p->max_trans_reply);
if(rdata == NULL) {
DEBUG(0,("api_rpc_trans_reply: malloc fail.\n"));
return False;
@ -3284,11 +3293,23 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
switch (subcommand) {
case 0x26:
/* dce/rpc command */
reply = rpc_command(p, data, tdscnt);
{
char *rdata = NULL;
int rlen = mdrcnt;
if (p->m)
{
reply = readwrite_pipe(p, data, tdscnt, &rdata, &rlen);
}
else
{
/* dce/rpc command */
reply = rpc_command(p, data, tdscnt);
}
if (reply)
reply = api_rpc_trans_reply(outbuf, p);
reply = api_rpc_trans_reply(outbuf, p, rdata, rlen);
break;
}
case 0x53:
/* Wait Named Pipe Handle state */
reply = api_WNPHS(outbuf, p, params, tpscnt);

View File

@ -129,7 +129,16 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
if (numtowrite == 0)
nwritten = 0;
else
nwritten = write_to_pipe(p, data, numtowrite);
{
if (p->m != NULL)
{
nwritten = write_pipe(p, data, numtowrite);
}
else
{
nwritten = write_to_pipe(p, data, numtowrite);
}
}
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
return (UNIXERROR(ERRDOS,ERRnoaccess));
@ -207,7 +216,14 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
nread = read_from_pipe(p, data, smb_maxcnt);
if (p->m != NULL)
{
nread = read_pipe(p, data, smb_maxcnt);
}
else
{
nread = read_from_pipe(p, data, smb_maxcnt);
}
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));

View File

@ -501,6 +501,8 @@ static void usage(char *pname)
****************************************************************************/
int main(int argc,char *argv[])
{
fstring sam_name;
extern BOOL append_log;
/* shall I run as a daemon */
BOOL is_daemon = False;
@ -680,11 +682,6 @@ static void usage(char *pname)
fstrcpy(global_myworkgroup, lp_workgroup());
if(!pdb_generate_sam_sid()) {
DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
exit(1);
}
CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
/* Setup the signals that allow the debug log level
@ -734,7 +731,23 @@ static void usage(char *pname)
/* possibly reload the services file. */
reload_services(True);
/* obtain or create a SAM SID */
if (lp_domain_logons())
{
fstrcpy(sam_name, global_myworkgroup);
}
else
{
fstrcpy(sam_name, global_myname);
}
if(!pdb_generate_sam_sid(sam_name, NULL))
{
DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
exit(1);
}
if (*lp_rootdir()) {
if (sys_chroot(lp_rootdir()) == 0)
DEBUG(2,("Changed root to %s\n", lp_rootdir()));