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:
parent
632b4f806e
commit
fbd17c8daf
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
92
source3/include/rpc_creds.h
Normal file
92
source3/include/rpc_creds.h
Normal 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 */
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
400
source3/lib/msrpc-client.c
Normal 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
328
source3/lib/msrpc_use.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
@ -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
194
source3/lib/util_array.c
Normal 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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -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.
|
||||
********************************************************************/
|
||||
|
578
source3/rpc_parse/parse_creds.c
Normal file
578
source3/rpc_parse/parse_creds.c
Normal 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);
|
||||
}
|
@ -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
@ -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);
|
||||
|
1077
source3/rpc_server/srv_pipe_srv.c
Normal file
1077
source3/rpc_server/srv_pipe_srv.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user