summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>2000-02-06 05:17:28 +0000
committerLuke Leighton <lkcl@samba.org>2000-02-06 05:17:28 +0000
commitcf34c0bec59dfd8b83edf3e111e925ccd3db1226 (patch)
treec68c44f0f3c93c46845e6fd4183b99328d4154d5
parent28aa3f66138b8be02d8198537b0e524b4b6b417b (diff)
downloadsamba-cf34c0bec59dfd8b83edf3e111e925ccd3db1226.tar.gz
samba-cf34c0bec59dfd8b83edf3e111e925ccd3db1226.tar.xz
samba-cf34c0bec59dfd8b83edf3e111e925ccd3db1226.zip
this is probably one of THE most reluctant commits i've ever made.
it's far-reaching, and necessary. this adds a vuser_struct tdb database, with a key [smbd's pid, vuid]. smbd uses it in every instance of standard_sub() and standard_sub_vuser(). that's almost every single SMB call for any IPC$ access. the next stage is to remove sesssetup_user, probably sessetup_user_list too, and review all occurences of standard_sub_basic used by smbd because if they use standard_sub_basic() they might be expecting to read sesssetup_user, and if they do _that_, they should be using standard_sub_vuser() instead. all i wanted was a means to get vuids across to msrpc daemons.
-rw-r--r--source/Makefile.in76
-rw-r--r--source/include/lib_smb_proto.h21
-rw-r--r--source/include/ntdomain.h3
-rw-r--r--source/include/proto.h98
-rw-r--r--source/include/rpc_client_proto.h3
-rw-r--r--source/include/rpc_creds.h3
-rw-r--r--source/include/rpc_netlogon.h8
-rw-r--r--source/include/rpc_parse_proto.h13
-rw-r--r--source/include/smb.h34
-rw-r--r--source/lib/msrpc-agent.c2
-rw-r--r--source/lib/msrpc-client.c24
-rw-r--r--source/lib/msrpc_use.c10
-rw-r--r--source/lib/set_uid.c12
-rw-r--r--source/lib/set_vuid.c6
-rw-r--r--source/lib/smbd_creds_db.c21
-rw-r--r--source/lib/stub_uid.c1
-rw-r--r--source/lib/util.c2
-rw-r--r--source/lib/vuser.c184
-rw-r--r--source/lib/vuser_db.c126
-rw-r--r--source/libsmb/clientgen.c6
-rw-r--r--source/msrpc/msrpcd_process.c60
-rw-r--r--source/netlogond/srv_netlogon_nt.c6
-rw-r--r--source/param/loadparm.c12
-rw-r--r--source/passdb/smbpassfile.c5
-rw-r--r--source/printing/printing.c51
-rw-r--r--source/rpc_client/cli_connect.c24
-rw-r--r--source/rpc_client/cli_login.c8
-rw-r--r--source/rpc_client/cli_pipe.c5
-rw-r--r--source/rpc_client/cli_pipe_netsec.c3
-rw-r--r--source/rpc_client/cli_pipe_noauth.c3
-rw-r--r--source/rpc_client/cli_pipe_ntlmssp.c5
-rw-r--r--source/rpc_parse/parse_creds.c11
-rw-r--r--source/rpc_parse/parse_net.c133
-rw-r--r--source/rpc_parse/parse_prs.c9
-rw-r--r--source/rpc_parse/parse_rpc.c5
-rw-r--r--source/rpc_parse/parse_vuid.c150
-rw-r--r--source/rpc_server/srv_netlog.c22
-rw-r--r--source/rpc_server/srv_pipe_hnd.c5
-rw-r--r--source/rpc_server/srv_pipe_netsec.c2
-rw-r--r--source/rpc_server/srv_pipe_ntlmssp.c7
-rw-r--r--source/script/mkproto.awk2
-rw-r--r--source/smbd/lanman.c128
-rw-r--r--source/smbd/open.c4
-rw-r--r--source/smbd/oplock.c2
-rw-r--r--source/smbd/password.c266
-rw-r--r--source/smbd/process.c10
-rw-r--r--source/smbd/reply.c19
-rw-r--r--source/smbd/service.c56
-rw-r--r--source/smbd/uid.c35
49 files changed, 1139 insertions, 562 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 1d76ce524dc..ff70ff074f5 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -148,7 +148,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/netmask.o lib/pidfile.o lib/replace.o \
lib/signal.o lib/slprintf.o lib/system.o lib/doscalls.o \
lib/time.o lib/ufc.o lib/util.o lib/genrand.o \
- lib/username.o lib/vuser.o \
+ lib/username.o \
lib/access.o lib/smbrun.o \
lib/bitmap.o lib/util_sid.o lib/snprintf.o \
lib/util_str.o lib/util_unistr.o \
@@ -177,6 +177,7 @@ LIBSMB_OBJ = libsmb/clientgen.o \
rpc_parse/parse_creds.o \
rpc_parse/parse_net.o \
rpc_parse/parse_ntlmssp.o rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
rpc_parse/parse_misc.o
RPC_SRVUTIL_OBJ = rpc_server/srv_pipe_srv.o \
@@ -253,11 +254,14 @@ SIDDB_OBJ = lib/sids.o
PROFILE_OBJ = profile/profile.o
SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/connection.o \
+ lib/vuser.o \
+ lib/vuser_db.o \
+ lib/set_uid.o \
smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \
smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o \
- smbd/uid.o lib/set_uid.o \
+ smbd/uid.o \
smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \
smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o smbd/vfs.o \
smbd/vfs-wrap.o smbd/dfs.o \
@@ -268,6 +272,8 @@ PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o
MSRPCD_OBJ = msrpc/msrpcd.o \
msrpc/msrpcd_process.o \
+ lib/vuser.o \
+ lib/vuser_db.o \
lib/set_vuid.o \
lib/set_uid.o
@@ -424,12 +430,13 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
-NMBD_OBJ = $(NMBD_OBJ1)
+NMBD_OBJ = $(NMBD_OBJ1) lib/vuser.o lib/vuser_db.o
NMBD_LIBS = $(SMBLIB) $(NMBLIB) $(SAMBALIB) $(UBIQXLIB)
SWAT_OBJ = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
web/swat.o libsmb/passchange.o $(LOCKING_OBJ) \
rpc_server/srv_lookup.o \
+ lib/vuser.o lib/vuser_db.o \
$(SIDDB_OBJ) \
$(UNIXPASSDB_OBJ) \
$(STUB_UID_OBJ)
@@ -439,21 +446,52 @@ SMBRUN_OBJ = utils/smbrun.o
SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o
-MAKE_SMBCODEPAGE_OBJ = utils/make_smbcodepage.o
-
-MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o
+MAKE_SMBCODEPAGE_OBJ = utils/make_smbcodepage.o \
+ rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_misc.o \
+ libsmb/smbdes.o \
+ lib/vuser.o lib/vuser_db.o
+
+MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o \
+ rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_misc.o \
+ libsmb/smbdes.o \
+ lib/vuser.o lib/vuser_db.o
STATUS_OBJ = utils/status.o $(LIBSTATUS_OBJ) $(LOCKING_OBJ) \
+ rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_misc.o \
+ libsmb/smbdes.o \
+ lib/vuser.o lib/vuser_db.o \
$(PROFILE_OBJ) $(STUB_UID_OBJ)
-TESTPARM_OBJ = utils/testparm.o
-
-TESTPRNS_OBJ = utils/testprns.o $(PRINTING_OBJ)
+TESTPARM_OBJ = utils/testparm.o \
+ rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_misc.o \
+ libsmb/smbdes.o \
+ lib/vuser.o lib/vuser_db.o
+
+TESTPRNS_OBJ = utils/testprns.o $(PRINTING_OBJ) \
+ rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_misc.o \
+ libsmb/smbdes.o \
+ lib/vuser.o lib/vuser_db.o
SMBPASSWD_OBJ = utils/smbpasswd.o libsmb/passchange.o \
libsmb/clienttrust.o \
rpc_server/srv_lookup.o \
rpc_client/cli_netlogon_sync.o \
+ lib/vuser.o lib/vuser_db.o \
$(SIDDB_OBJ) $(STUB_UID_OBJ)
SMBPASSWD_LIBS = $(SAMBA_LIBS) $(SMBPWLIB) $(UBIQXLIB)
@@ -479,6 +517,7 @@ RPCCLIENT_OBJ = rpcclient/rpcclient.o \
rpcclient/cmd_spoolss.o \
rpcclient/cmd_eventlog.o \
$(SIDDB_OBJ) \
+ lib/vuser.o lib/vuser_db.o \
$(STUB_UID_OBJ)
RPCCLIENT_LIBS = $(SAMBA_LIBS) $(SMBPWLIB) $(UBIQXLIB)
@@ -486,7 +525,8 @@ SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \
smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
smbwrapper/realcalls.o smbwrapper/shared.o
-CLIENT_OBJ = client/client.o client/clitar.o
+CLIENT_OBJ = client/client.o client/clitar.o \
+ lib/vuser.o lib/vuser_db.o
CLIENT_LIBS = $(SMBLIB) $(NMBLIB) $(SAMBALIB)
MOUNT_OBJ = client/smbmount.o client/clientutil.o \
@@ -501,11 +541,23 @@ UMOUNT_OBJ = client/smbumount.o \
NMB_AGENT_OBJ = utils/nmb-agent.o \
$(RPC_PARSE_OBJ2)
-NMBLOOKUP_OBJ = utils/nmblookup.o
+NMBLOOKUP_OBJ = utils/nmblookup.o \
+ rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_misc.o \
+ libsmb/smbdes.o \
+ lib/vuser.o lib/vuser_db.o
#$(RPC_PARSE_OBJ2)
-DEBUG2HTML_OBJ = utils/debug2html.o
+DEBUG2HTML_OBJ = utils/debug2html.o \
+ rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_misc.o \
+ libsmb/smbdes.o \
+ lib/vuser.o lib/vuser_db.o
SMB_AGENT_OBJ = utils/smb-agent.o \
$(RPC_PARSE_OBJ2) rpc_client/cli_use.o
diff --git a/source/include/lib_smb_proto.h b/source/include/lib_smb_proto.h
index 56b9b2212a5..63bac8bf20f 100644
--- a/source/include/lib_smb_proto.h
+++ b/source/include/lib_smb_proto.h
@@ -245,7 +245,7 @@ char *smb_errstr(char *inbuf);
/*The following definitions come from passdb/smbpassfile.c */
-BOOL trust_password_lock( char *domain, char *name, BOOL update);
+BOOL trust_password_lock( const char *domain, const char *name, BOOL update);
BOOL trust_password_unlock(void);
BOOL trust_password_delete( char *domain, char *name );
BOOL get_trust_account_password( uchar *ret_pwd, time_t *pass_last_set_time);
@@ -281,13 +281,13 @@ 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,
- uint32 pid,
+ const vuser_key *key,
const struct ntuser_creds *ntu,
BOOL reuse);
BOOL create_user_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr);
/*The following definitions come from rpc_parse/parse_misc.c */
@@ -507,7 +507,6 @@ BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
const DOM_CRED *srv_creds,
uint16 switch_value,
NET_USER_INFO_3 *user_info,
- uint32 auth_resp,
uint32 status);
BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
@@ -609,4 +608,18 @@ BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
uint32 ptr_uint32, uint32 data_size);
int prs_tdb_store(TDB_CONTEXT *tdb, int flgs, prs_struct *pk, prs_struct *pd);
void prs_tdb_fetch(TDB_CONTEXT *tdb, prs_struct *pk, prs_struct *pd);
+
+/*The following definitions come from rpc_parse/parse_vuid.c */
+
+BOOL vuid_io_key(char *desc, vuser_key *r_u, prs_struct *ps, int depth);
+BOOL make_vuid_user_struct(user_struct *r_u,
+ uid_t uid, gid_t gid,
+ const char* name,
+ const char* requested_name,
+ const char* real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t *groups,
+ const NET_USER_INFO_3 *usr);
+BOOL vuid_io_user_struct(char *desc, user_struct *r_u, prs_struct *ps, int depth);
+void vuid_free_user_struct(user_struct *r_u);
#endif /* _LIB_SMB_PROTO_H_ */
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index 5756fda5d67..a36aba06490 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -135,8 +135,7 @@ typedef struct rpcsrv_struct
RPC_HDR_RB hdr_rb;
RPC_HDR_REQ hdr_req;
- uint16 vuid;
- uint16 remote_pid;
+ vuser_key key;
} rpcsrv_struct;
diff --git a/source/include/proto.h b/source/include/proto.h
index 863a8380e70..d6e3a5cbfc6 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -298,20 +298,22 @@ 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,
- uint32 pid,
+ const vuser_key *key,
const char* pipename,
const struct user_creds *usr);
-struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid);
+struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc,
+ const vuser_key *key);
void msrpc_shutdown(struct msrpc_state *msrpc);
BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
- const char *pipe_name);
+ const vuser_key *key,
+ 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,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr_creds,
BOOL redir);
BOOL msrpc_use_del(const char* pipe_name,
@@ -351,7 +353,7 @@ BOOL become_uid(uid_t uid);
BOOL become_gid(gid_t gid);
BOOL unbecome_to_initial_uid(void);
BOOL become_id(uid_t uid,gid_t gid);
-BOOL become_unix_sec_ctx(uint16 vuid, connection_struct *conn,
+BOOL become_unix_sec_ctx(const vuser_key *k, connection_struct *conn,
uid_t new_uid, gid_t new_gid,
int n_groups, gid_t* groups);
BOOL become_guest(void);
@@ -361,7 +363,7 @@ void unbecome_root(BOOL restore_dir);
/*The following definitions come from lib/set_vuid.c */
void init_vuid(void);
-BOOL become_vuser(uint16 vuid);
+BOOL become_vuser(const vuser_key *k);
BOOL unbecome_vuser(void);
/*The following definitions come from lib/sids.c */
@@ -536,7 +538,7 @@ void standard_sub(connection_struct *conn, user_struct *vuser, char *str);
BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
struct hostent *Get_Hostbyname(const char *name);
BOOL process_exists(int pid);
-int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
+int get_unixgroups(const char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
BOOL get_unix_grps(int *p_ngroups, struct group **p_groups);
void free_unix_grps(int ngroups, struct group *p_groups);
char *gidtoname(gid_t gid);
@@ -775,16 +777,30 @@ void start_agent(struct vagent_ops *va);
/*The following definitions come from lib/vuser.c */
-user_struct *get_valid_user_struct(uint16 vuid);
-void invalidate_vuid(uint16 vuid);
-char *validated_username(uint16 vuid);
-uint16 create_vuid(uid_t uid, gid_t gid, int n_groups, gid_t *groups,
- char *unix_name, char *requested_name,
- char *real_name,
+user_struct *get_valid_user_struct(const vuser_key *key);
+void invalidate_vuid(vuser_key *key);
+BOOL validated_username(vuser_key *key, char *name, size_t len);
+uint16 create_vuid(pid_t pid,
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t *groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
BOOL guest, const NET_USER_INFO_3 *info3);
-uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest, const NET_USER_INFO_3 *info3);
+uint16 register_vuid(pid_t pid,
+ uid_t uid,gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest,
+ const NET_USER_INFO_3 *info3);
BOOL check_vuser_ok(struct uid_cache *cache, user_struct *vuser,int snum);
+/*The following definitions come from lib/vuser_db.c */
+
+BOOL tdb_lookup_vuid( const vuser_key *uk, user_struct *usr);
+BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr);
+BOOL vuid_init_db(void);
+
/*The following definitions come from libsmb/clientgen.c */
int cli_set_port(struct cli_state *cli, int port);
@@ -1114,7 +1130,7 @@ void exit_server(char *reason);
/*The following definitions come from msrpc/msrpcd_process.c */
-BOOL get_user_creds(int c, struct user_creds *usr, uint32 *pid);
+BOOL get_user_creds(int c, struct user_creds *usr, vuser_key *uk);
void close_srv_auth_array(rpcsrv_struct *l);
void add_srv_auth_fn(rpcsrv_struct *l, srv_auth_fns *fn);
BOOL msrpcd_init(int c, msrpc_pipes_struct *p);
@@ -1165,7 +1181,6 @@ uint32 _net_sam_logon(const DOM_SAM_INFO *sam_id,
DOM_CRED *srv_creds,
uint16 *switch_value,
NET_USER_INFO_3 *user,
- uint32 *auth_resp,
uint16 remote_pid);
uint32 _net_sam_logoff(const DOM_SAM_INFO *sam_id,
DOM_CRED *srv_creds,
@@ -1644,10 +1659,10 @@ int lp_stat_cache_size(void);
int lp_map_to_guest(void);
int lp_ldap_port(void);
int lp_ldap_protocol_version(void);
-char *lp_logon_script(uint16 );
-char *lp_logon_path(uint16 );
-char *lp_logon_drive(uint16 );
-char *lp_logon_home(uint16 );
+char *lp_logon_script(const vuser_key* );
+char *lp_logon_path(const vuser_key* );
+char *lp_logon_drive(const vuser_key* );
+char *lp_logon_home(const vuser_key* );
char *lp_preexec(int );
char *lp_postexec(int );
char *lp_rootpreexec(int );
@@ -1947,7 +1962,7 @@ BOOL local_password_change(char *user_name,
/*The following definitions come from passdb/smbpassfile.c */
-BOOL trust_password_lock( char *domain, char *name, BOOL update);
+BOOL trust_password_lock( const char *domain, const char *name, BOOL update);
BOOL trust_password_unlock(void);
BOOL trust_password_delete( char *domain, char *name );
BOOL get_trust_account_password( uchar *ret_pwd, time_t *pass_last_set_time);
@@ -2004,18 +2019,18 @@ int sysv_printername_ok(char *name);
/*The following definitions come from printing/printing.c */
void lpq_reset(int snum);
-void print_file(connection_struct *conn, uint16 vuid,
+void print_file(connection_struct *conn, const vuser_key *key,
int snum, files_struct *file);
-int get_printqueue(int snum, connection_struct *conn, uint16 vuid,
+int get_printqueue(int snum, connection_struct *conn, const vuser_key *key,
print_queue_struct **queue,
print_status_struct *status);
-void del_printqueue(connection_struct *conn,uint16 vuid,
+void del_printqueue(connection_struct *conn,const vuser_key *key,
int snum,int jobid);
-void status_printjob(connection_struct *conn,uint16 vuid,
+void status_printjob(connection_struct *conn,const vuser_key *key,
int snum,int jobid,int status);
int printjob_encode(int snum, int job);
void printjob_decode(int jobid, int *snum, int *job);
-uint32 status_printqueue(connection_struct *conn,uint16 vuid,
+uint32 status_printqueue(connection_struct *conn,const vuser_key *key,
int snum,int status);
void load_printers(void);
@@ -2213,7 +2228,8 @@ BOOL synchronise_passdb(void);
/*The following definitions come from rpc_client/cli_pipe.c */
-BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, uint8 flags,
+BOOL create_rpc_request(prs_struct *rhdr, uint16 vuid,
+ uint8 op_num, uint8 flags,
int data_len,
int auth_len);
BOOL rpc_api_pipe_req(struct cli_connection *con, uint8 opnum,
@@ -2728,13 +2744,13 @@ 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,
- uint32 pid,
+ const vuser_key *key,
const struct ntuser_creds *ntu,
BOOL reuse);
BOOL create_user_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr);
/*The following definitions come from rpc_parse/parse_misc.c */
@@ -2954,7 +2970,6 @@ BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
const DOM_CRED *srv_creds,
uint16 switch_value,
NET_USER_INFO_3 *user_info,
- uint32 auth_resp,
uint32 status);
BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
@@ -3098,7 +3113,8 @@ BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc,
uint8 num_results, uint16 result, uint16 reason,
RPC_IFACE *transfer);
BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
-BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum);
+BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 vuid,
+ uint16 opnum);
BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
@@ -3134,6 +3150,20 @@ BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
void free_sec_desc_buf(SEC_DESC_BUF *buf);
BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+/*The following definitions come from rpc_parse/parse_vuid.c */
+
+BOOL vuid_io_key(char *desc, vuser_key *r_u, prs_struct *ps, int depth);
+BOOL make_vuid_user_struct(user_struct *r_u,
+ uid_t uid, gid_t gid,
+ const char* name,
+ const char* requested_name,
+ const char* real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t *groups,
+ const NET_USER_INFO_3 *usr);
+BOOL vuid_io_user_struct(char *desc, user_struct *r_u, prs_struct *ps, int depth);
+void vuid_free_user_struct(user_struct *r_u);
+
/*The following definitions come from rpc_server/srv_brs.c */
BOOL api_brs_rpc(rpcsrv_struct *p);
@@ -4149,9 +4179,10 @@ BOOL password_ok(const char *orig_user, const char *domain,
const char *smb_ntpasswd, int smb_ntpasslen,
struct passwd *pwd,
NET_USER_INFO_3 *info3);
-BOOL authorise_login(int snum,char *user, char *domain,
+BOOL authorise_login(int snum, char *user, char *domain,
char *password, int pwlen,
- BOOL *guest,BOOL *force,uint16 vuid);
+ BOOL *guest,BOOL *force,
+ const vuser_key *key);
BOOL check_hosts_equiv(char *user);
/*The following definitions come from smbd/pipes.c */
@@ -4285,6 +4316,7 @@ int reply_trans2(connection_struct *conn,
/*The following definitions come from smbd/uid.c */
BOOL become_user(connection_struct *conn, uint16 vuid);
+BOOL become_userk(connection_struct *conn, const vuser_key *key);
BOOL unbecome_user(void );
/*The following definitions come from smbd/vfs-wrap.c */
diff --git a/source/include/rpc_client_proto.h b/source/include/rpc_client_proto.h
index 794a1216ce9..f747e1cc99a 100644
--- a/source/include/rpc_client_proto.h
+++ b/source/include/rpc_client_proto.h
@@ -189,7 +189,8 @@ BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname,
/*The following definitions come from rpc_client/cli_pipe.c */
-BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, uint8 flags,
+BOOL create_rpc_request(prs_struct *rhdr, uint16 vuid,
+ uint8 op_num, uint8 flags,
int data_len,
int auth_len);
BOOL rpc_api_pipe_req(struct cli_connection *con, uint8 opnum,
diff --git a/source/include/rpc_creds.h b/source/include/rpc_creds.h
index fc84ad3b956..2b897da6791 100644
--- a/source/include/rpc_creds.h
+++ b/source/include/rpc_creds.h
@@ -79,7 +79,8 @@ typedef struct cred_command
{
uint16 version;
uint16 command;
- uint32 pid; /* unique process id */
+
+ vuser_key key;
fstring name;
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index 5b20fe91177..aa71475916b 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -47,8 +47,6 @@
/* NET_USER_INFO_3 */
typedef struct net_user_info_3
{
- uint32 ptr_user_info;
-
NTTIME logon_time; /* logon time */
NTTIME logoff_time; /* logoff time */
NTTIME kickoff_time; /* kickoff time */
@@ -99,6 +97,8 @@ typedef struct net_user_info_3
DOM_SID2 dom_sid; /* domain SID */
DOM_SID2 other_sids[LSA_MAX_SIDS]; /* undocumented - domain SIDs */
+ uint32 auth_resp; /* 1 - Authoritative response */
+
} NET_USER_INFO_3;
@@ -385,9 +385,9 @@ typedef struct net_r_sam_logon_info
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
uint16 switch_value; /* 3 - indicates type of USER INFO */
- NET_USER_INFO_3 *user;
+ uint32 ptr_user_info;
- uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
+ NET_USER_INFO_3 *user;
uint32 status; /* return code */
diff --git a/source/include/rpc_parse_proto.h b/source/include/rpc_parse_proto.h
index 47241223af9..a6c96ba654c 100644
--- a/source/include/rpc_parse_proto.h
+++ b/source/include/rpc_parse_proto.h
@@ -17,20 +17,22 @@ 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,
- uint32 pid,
+ const vuser_key *key,
const char* pipename,
const struct user_creds *usr);
-struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid);
+struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc,
+ const vuser_key *key);
void msrpc_shutdown(struct msrpc_state *msrpc);
BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
- const char *pipe_name);
+ const vuser_key *key,
+ 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,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr_creds,
BOOL redir);
BOOL msrpc_use_del(const char* pipe_name,
@@ -265,7 +267,8 @@ BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc,
uint8 num_results, uint16 result, uint16 reason,
RPC_IFACE *transfer);
BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
-BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum);
+BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 vuid,
+ uint16 opnum);
BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
diff --git a/source/include/smb.h b/source/include/smb.h
index 7072d65e761..b2b4a57cb1d 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -596,16 +596,6 @@ typedef struct connection_struct
} connection_struct;
-struct current_user
-{
- connection_struct *conn;
- uint16 vuid;
- uid_t uid;
- gid_t gid;
- int ngroups;
- gid_t *groups;
-};
-
/* Domain controller authentication protocol info */
struct dcinfo
{
@@ -1683,6 +1673,14 @@ extern int unix_ERR_code;
#include "smb_macros.h"
#include "nt_printing.h"
+
+typedef struct
+{
+ uint32 pid;
+ uint16 vuid;
+
+} vuser_key;
+
#include "ntdomain.h"
typedef struct
@@ -1704,6 +1702,16 @@ typedef struct
} user_struct;
+struct current_user
+{
+ connection_struct *conn;
+ vuser_key key;
+ uid_t uid;
+ gid_t gid;
+ int ngroups;
+ gid_t *groups;
+};
+
/* A netbios name structure. */
struct nmb_name {
char name[17];
@@ -1811,6 +1819,8 @@ struct ntdom_info
int max_recv_frag;
int max_xmit_frag;
+
+ vuser_key key;
};
struct msrpc_state
@@ -1826,14 +1836,10 @@ struct msrpc_state
BOOL initialised;
char *inbuf;
char *outbuf;
-
- uint32 pid;
};
typedef struct netsec_creds
{
- uint32 pid;
-
fstring domain;
fstring myname;
diff --git a/source/lib/msrpc-agent.c b/source/lib/msrpc-agent.c
index 932dd72b86d..4d2e5b3abeb 100644
--- a/source/lib/msrpc-agent.c
+++ b/source/lib/msrpc-agent.c
@@ -128,7 +128,7 @@ static struct msrpc_state *init_client_connection(int c)
if (new_con)
{
uint32 status = 0;
- n = msrpc_use_add(pipe_name, cmd.pid, &usr, False);
+ n = msrpc_use_add(pipe_name, &cmd.key, &usr, False);
if (n == NULL)
{
diff --git a/source/lib/msrpc-client.c b/source/lib/msrpc-client.c
index 0beaed85b47..8adfa65043b 100644
--- a/source/lib/msrpc-client.c
+++ b/source/lib/msrpc-client.c
@@ -202,6 +202,7 @@ void msrpc_sockopt(struct msrpc_state *msrpc, char *options)
static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
+ const vuser_key *key,
const struct user_creds *usr)
{
struct msrpc_state msrpc_redir;
@@ -217,7 +218,7 @@ static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
if (!create_user_creds(&ps, msrpc->pipe_name, 0x0, command,
- msrpc->pid, usr))
+ key, usr))
{
DEBUG(0,("could not parse credentials\n"));
close(sock);
@@ -267,6 +268,7 @@ static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
}
static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
+ const vuser_key *key,
const char* pipe_name,
const struct user_creds *usr)
{
@@ -284,7 +286,7 @@ static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
msrpc->fd = sock;
- if (!msrpc_authenticate(msrpc, usr))
+ if (!msrpc_authenticate(msrpc, key, usr))
{
DEBUG(0,("authenticate failed\n"));
close(msrpc->fd);
@@ -296,12 +298,12 @@ static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
}
BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
- uint32 pid,
+ const vuser_key *key,
const char* pipename,
const struct user_creds *usr)
{
ZERO_STRUCTP(msrpc);
- if (!msrpc_initialise(msrpc, pid))
+ if (!msrpc_initialise(msrpc, key))
{
DEBUG(0,("unable to initialise msrpcent connection.\n"));
return False;
@@ -309,7 +311,7 @@ BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
msrpc_init_creds(msrpc, usr);
- if (!msrpc_establish_connection(msrpc, pipename))
+ if (!msrpc_establish_connection(msrpc, key, pipename))
{
msrpc_shutdown(msrpc);
return False;
@@ -321,7 +323,8 @@ BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
/****************************************************************************
initialise a msrpcent structure
****************************************************************************/
-struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid)
+struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc,
+ const vuser_key *key)
{
if (!msrpc) {
msrpc = (struct msrpc_state *)malloc(sizeof(*msrpc));
@@ -346,7 +349,7 @@ struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid)
msrpc->initialised = 1;
msrpc_init_creds(msrpc, NULL);
- msrpc->pid = pid;
+ msrpc->nt.key.vuid = UID_FIELD_INVALID;
return msrpc;
}
@@ -374,7 +377,8 @@ void msrpc_shutdown(struct msrpc_state *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)
+ const vuser_key *key,
+ const char *pipe_name)
{
DEBUG(5,("msrpc_establish_connection: connecting to %s (%s) - %s\n",
pipe_name,
@@ -389,7 +393,7 @@ BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
if (msrpc->fd == -1 && msrpc->redirect)
{
- if (msrpc_init_redirect(msrpc, pipe_name, &msrpc->usr))
+ if (msrpc_init_redirect(msrpc, key, pipe_name, &msrpc->usr))
{
DEBUG(10,("msrpc_establish_connection: redirected OK\n"));
return True;
@@ -411,7 +415,7 @@ BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
}
}
- if (!msrpc_authenticate(msrpc, &msrpc->usr))
+ if (!msrpc_authenticate(msrpc, key, &msrpc->usr))
{
DEBUG(0,("authenticate failed\n"));
close(msrpc->fd);
diff --git a/source/lib/msrpc_use.c b/source/lib/msrpc_use.c
index 7ea1394bd0b..c2bd20478a4 100644
--- a/source/lib/msrpc_use.c
+++ b/source/lib/msrpc_use.c
@@ -171,7 +171,7 @@ static struct msrpc_use *msrpc_find(const char* pipe_name,
create a new client state from user credentials
****************************************************************************/
static struct msrpc_use *msrpc_use_get(const char* pipe_name,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr_creds)
{
struct msrpc_use *cli = (struct msrpc_use*)malloc(sizeof(*cli));
@@ -183,7 +183,7 @@ static struct msrpc_use *msrpc_use_get(const char* pipe_name,
memset(cli, 0, sizeof(*cli));
- cli->cli = msrpc_initialise(NULL, pid);
+ cli->cli = msrpc_initialise(NULL, key);
if (cli->cli == NULL)
{
@@ -199,7 +199,7 @@ static struct msrpc_use *msrpc_use_get(const char* pipe_name,
init client state
****************************************************************************/
struct msrpc_state *msrpc_use_add(const char* pipe_name,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr_creds,
BOOL redir)
{
@@ -225,10 +225,10 @@ struct msrpc_state *msrpc_use_add(const char* pipe_name,
* allocate
*/
- cli = msrpc_use_get(pipe_name, pid, usr_creds);
+ cli = msrpc_use_get(pipe_name, key, usr_creds);
cli->cli->redirect = redir;
- if (!msrpc_establish_connection(cli->cli, pipe_name))
+ if (!msrpc_establish_connection(cli->cli, key, pipe_name))
{
DEBUG(0,("msrpc_use_add: connection failed\n"));
cli->cli = NULL;
diff --git a/source/lib/set_uid.c b/source/lib/set_uid.c
index 8474837d2a9..6f0a099e7ed 100644
--- a/source/lib/set_uid.c
+++ b/source/lib/set_uid.c
@@ -52,7 +52,7 @@ void init_uid(void)
initial_gid = getegid();
current_user.conn = NULL;
- current_user.vuid = UID_FIELD_INVALID;
+ current_user.key.vuid = UID_FIELD_INVALID;
current_user.ngroups = 0;
current_user.groups = NULL;
@@ -196,7 +196,7 @@ BOOL unbecome_to_initial_uid(void)
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
current_user.conn = NULL;
- current_user.vuid = UID_FIELD_INVALID;
+ current_user.key.vuid = UID_FIELD_INVALID;
return(True);
}
@@ -212,7 +212,7 @@ BOOL become_id(uid_t uid,gid_t gid)
/****************************************************************************
become the user of a connection number
****************************************************************************/
-BOOL become_unix_sec_ctx(uint16 vuid, connection_struct *conn,
+BOOL become_unix_sec_ctx(const vuser_key *k, connection_struct *conn,
uid_t new_uid, gid_t new_gid,
int n_groups, gid_t* groups)
{
@@ -223,7 +223,7 @@ BOOL become_unix_sec_ctx(uint16 vuid, connection_struct *conn,
if (current_user.uid == new_uid)
{
- DEBUG(4,("Skipping become_vuser - already user\n"));
+ DEBUG(4,("Skipping become_unix_sec_ctx - already user\n"));
return(True);
}
@@ -261,7 +261,7 @@ BOOL become_unix_sec_ctx(uint16 vuid, connection_struct *conn,
}
current_user.conn = conn;
- current_user.vuid = vuid;
+ current_user.key = *k;
DEBUG(5,("become_unix_sec_ctx uid=(%d,%d) gid=(%d,%d)\n",
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
@@ -296,7 +296,7 @@ BOOL become_guest(void)
}
current_user.conn = NULL;
- current_user.vuid = UID_FIELD_INVALID;
+ current_user.key.vuid = UID_FIELD_INVALID;
return(ret);
}
diff --git a/source/lib/set_vuid.c b/source/lib/set_vuid.c
index 3a635bbaea0..b25963ffbea 100644
--- a/source/lib/set_vuid.c
+++ b/source/lib/set_vuid.c
@@ -34,16 +34,16 @@ void init_vuid(void)
/****************************************************************************
become the user of a connection number
****************************************************************************/
-BOOL become_vuser(uint16 vuid)
+BOOL become_vuser(const vuser_key *k)
{
- user_struct *vuser = get_valid_user_struct(vuid);
+ user_struct *vuser = get_valid_user_struct(k);
unbecome_vuser();
if((vuser != NULL) && !check_vuser_ok(&vcache, vuser, -1))
return False;
- return become_unix_sec_ctx(vuid, NULL, vuser->uid, vuser->gid,
+ return become_unix_sec_ctx(k, NULL, vuser->uid, vuser->gid,
vuser->n_groups, vuser->groups);
}
diff --git a/source/lib/smbd_creds_db.c b/source/lib/smbd_creds_db.c
index 8156dec0965..232d8d9c52d 100644
--- a/source/lib/smbd_creds_db.c
+++ b/source/lib/smbd_creds_db.c
@@ -1,3 +1,24 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ 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"
extern int DEBUGLEVEL;
diff --git a/source/lib/stub_uid.c b/source/lib/stub_uid.c
index 3aede99c3af..25f0bd5b69d 100644
--- a/source/lib/stub_uid.c
+++ b/source/lib/stub_uid.c
@@ -29,4 +29,3 @@ void become_root(BOOL save_dir)
void unbecome_root(BOOL restore_dir)
{
}
-
diff --git a/source/lib/util.c b/source/lib/util.c
index 404f4862e97..698329ff8c5 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1936,7 +1936,7 @@ BOOL process_exists(int pid)
/****************************************************************************
Setup the groups a user belongs to.
****************************************************************************/
-int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
+int get_unixgroups(const char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
{
int i,ngroups;
gid_t grp = 0;
diff --git a/source/lib/vuser.c b/source/lib/vuser.c
index 013671aff1a..9d9ce67ff09 100644
--- a/source/lib/vuser.c
+++ b/source/lib/vuser.c
@@ -24,7 +24,6 @@
extern int DEBUGLEVEL;
/* this holds info on user ids that are already validated for this VC */
-static user_struct *validated_users = NULL;
static int num_validated_users = 0;
/****************************************************************************
@@ -32,96 +31,120 @@ check if a uid has been validated, and return an pointer to the user_struct
if it has. NULL if not. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
-user_struct *get_valid_user_struct(uint16 vuid)
+user_struct *get_valid_user_struct(const vuser_key *key)
{
- if (vuid == UID_FIELD_INVALID)
- return NULL;
- vuid -= VUID_OFFSET;
- if ((vuid >= (uint16)num_validated_users) ||
- (validated_users[vuid].uid == (uid_t)-1) || (validated_users[vuid].gid == (gid_t)-1))
- return NULL;
- return &validated_users[vuid];
+ user_struct *usr;
+ if (key == NULL)
+ {
+ return NULL;
+ }
+
+ if (key->vuid == UID_FIELD_INVALID)
+ {
+ return NULL;
+ }
+ usr = (user_struct *)malloc(sizeof(*usr));
+ if (usr == NULL)
+ {
+ return NULL;
+ }
+ if (!tdb_lookup_vuid(key, usr))
+ {
+ vuid_free_user_struct(usr);
+ safe_free(usr);
+ return NULL;
+ }
+ if (usr->uid == (uid_t)-1 || usr->gid == (gid_t)-1)
+ {
+ vuid_free_user_struct(usr);
+ safe_free(usr);
+ }
+ return usr;
}
/****************************************************************************
invalidate a uid
****************************************************************************/
-void invalidate_vuid(uint16 vuid)
+void invalidate_vuid(vuser_key *key)
{
- user_struct *vuser = get_valid_user_struct(vuid);
+ user_struct *vuser = get_valid_user_struct(key);
- if (vuser == NULL) return;
+ if (vuser == NULL) return;
- vuser->uid = (uid_t)-1;
- vuser->gid = (gid_t)-1;
+ vuser->uid = (uid_t)-1;
+ vuser->gid = (gid_t)-1;
- /* same number of igroups as groups */
- vuser->n_groups = 0;
+ vuser->n_groups = 0;
+ safe_free(vuser->groups);
+ vuser->groups = NULL;
- if (vuser->groups)
- free((char *)vuser->groups);
+ tdb_store_vuid(key, vuser);
- vuser->groups = NULL;
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
}
/****************************************************************************
return a validated username
****************************************************************************/
-char *validated_username(uint16 vuid)
+BOOL validated_username(vuser_key *key, char *name, size_t len)
{
- user_struct *vuser = get_valid_user_struct(vuid);
- if (vuser == NULL)
- return 0;
- return(vuser->name);
+ user_struct *vuser = get_valid_user_struct(key);
+ if (vuser == NULL)
+ {
+ return False;
+ }
+ safe_strcpy(name, vuser->name, len-1);
+ return True;
}
-
/****************************************************************************
register a uid/name pair as being valid and that a valid password
has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
-uint16 create_vuid(uid_t uid, gid_t gid, int n_groups, gid_t *groups,
- char *unix_name, char *requested_name,
- char *real_name,
+uint16 create_vuid(pid_t pid,
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t *groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
BOOL guest, const NET_USER_INFO_3 *info3)
{
- user_struct *vuser;
+ user_struct vuser;
+ vuser_key key;
uint16 vuid;
- validated_users = (user_struct *)Realloc(validated_users,
- sizeof(user_struct)*
- (num_validated_users+1));
-
- if (!validated_users)
- {
- DEBUG(0,("Failed to realloc users struct!\n"));
- num_validated_users = 0;
- return UID_FIELD_INVALID;
- }
-
- vuser = &validated_users[num_validated_users];
- num_validated_users++;
-
- vuser->uid = uid;
- vuser->gid = gid;
- vuser->guest = guest;
- fstrcpy(vuser->name,unix_name);
- fstrcpy(vuser->requested_name,requested_name);
- fstrcpy(vuser->real_name,real_name);
- memcpy(&vuser->usr, info3, sizeof(vuser->usr));
-
- vuser->n_groups = n_groups;
- vuser->groups = groups;
-
- vuid = (uint16)((num_validated_users - 1) + VUID_OFFSET);
- DEBUG(3,("uid %d vuid %d registered to name %s\n",(int)uid, vuid, unix_name));
- dump_data_pw("vuid usr sess key:\n", vuser->usr.user_sess_key,
- sizeof(vuser->usr.user_sess_key));
-
- return vuid;
+ vuser.uid = uid;
+ vuser.gid = gid;
+ vuser.guest = guest;
+ fstrcpy(vuser.name,unix_name);
+ fstrcpy(vuser.requested_name,requested_name);
+ fstrcpy(vuser.real_name,real_name);
+ memcpy(&vuser.usr, info3, sizeof(vuser.usr));
+
+ vuser.n_groups = n_groups;
+ vuser.groups = groups;
+
+ num_validated_users++;
+ vuid = (uint16)((num_validated_users - 1) + VUID_OFFSET);
+
+ DEBUG(3,("uid %d vuid %d registered to unix name %s\n",
+ (int)uid, vuid, unix_name));
+ dump_data_pw("vuid usr sess key:\n", vuser.usr.user_sess_key,
+ sizeof(vuser.usr.user_sess_key));
+
+ key.pid = (uint32)pid;
+ key.vuid = vuid;
+
+ if (!tdb_store_vuid(&key, &vuser))
+ {
+ return UID_FIELD_INVALID;
+ }
+
+ return vuid;
}
/****************************************************************************
@@ -129,7 +152,12 @@ register a uid/name pair as being valid and that a valid password
has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
-uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest, const NET_USER_INFO_3 *info3)
+uint16 register_vuid(pid_t pid,
+ uid_t uid,gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest,
+ const NET_USER_INFO_3 *info3)
{
int n_groups = 0;
gid_t *groups = NULL;
@@ -140,38 +168,6 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
if(lp_security() == SEC_SHARE)
return UID_FIELD_INVALID;
-#if 0
- /*
- * After observing MS-Exchange services writing to a Samba share
- * I belive this code is incorrect. Each service does its own
- * sessionsetup_and_X for the same user, and as each service shuts
- * down, it does a user_logoff_and_X. As we are consolidating multiple
- * sessionsetup_and_X's onto the same vuid here, when the first service
- * shuts down, it invalidates all the open files for the other services.
- * Hence I am removing this code and forcing each sessionsetup_and_X
- * to get a new vuid.
- * Jeremy Allison. (jallison@whistle.com).
- */
-
- int i;
- for(i = 0; i < num_validated_users; i++) {
- vuser = &validated_users[i];
- if ( vuser->uid == uid )
- return (uint16)(i + VUID_OFFSET); /* User already validated */
- }
-#endif
-
- validated_users = (user_struct *)Realloc(validated_users,
- sizeof(user_struct)*
- (num_validated_users+1));
-
- if (!validated_users)
- {
- DEBUG(0,("Failed to realloc users struct!\n"));
- num_validated_users = 0;
- return UID_FIELD_INVALID;
- }
-
/* Find all the groups this uid is in and store them.
Used by become_user() */
get_unixgroups(unix_name,uid,gid,
@@ -191,7 +187,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
}
}
- return create_vuid(uid, gid, n_groups, groups,
+ return create_vuid(pid, uid, gid, n_groups, groups,
unix_name, requested_name,
real_name,
guest, info3);
diff --git a/source/lib/vuser_db.c b/source/lib/vuser_db.c
new file mode 100644
index 00000000000..a0a1d319321
--- /dev/null
+++ b/source/lib/vuser_db.c
@@ -0,0 +1,126 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ 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.
+*/
+
+/*
+ * this module stores a user_struct which can be globally accessed (by root)
+ * across process boundaries, in order to obtain info about users currently
+ * accessing * samba.
+ *
+ * the database key is the process number (pid) of the creater of the
+ * structure plus the vuid - SMB virtual user id. NORMALLY, this would
+ * be smbd pid and an smbd-generated vuid.
+ *
+ */
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+static TDB_CONTEXT *tdb = NULL;
+
+BOOL tdb_lookup_vuid( const vuser_key *uk, user_struct *usr)
+{
+ prs_struct key;
+ prs_struct data;
+ vuser_key k = *uk;
+
+ ZERO_STRUCTP(usr);
+
+ if (tdb == NULL)
+ {
+ if (!vuid_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10,("lookup user %x,%x\n", uk->pid, uk->vuid));
+
+ prs_init(&key, 0, 4, False);
+ if (!vuid_io_key("key", &k, &key, 0))
+ {
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (!vuid_io_user_struct("usr", usr, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr)
+{
+ prs_struct key;
+ prs_struct data;
+ vuser_key k = *uk;
+
+ if (tdb == NULL)
+ {
+ if (!vuid_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10,("storing user %x,%x\n", uk->pid, uk->vuid));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!vuid_io_key("key", &k, &key, 0) ||
+ !vuid_io_user_struct("usr", usr, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+BOOL vuid_init_db(void)
+{
+ tdb = tdb_open(lock_path("vuid.tdb"), 0, 0, O_RDWR | O_CREAT, 0600);
+
+ if (tdb == NULL)
+ {
+ DEBUG(0,("vuid_init_db: failed\n"));
+ return False;
+ }
+
+ DEBUG(10,("vuid_init_db: opened\n"));
+
+ return True;
+}
+
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index bc6e2c05d73..33671fdcc3c 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -2979,6 +2979,7 @@ static BOOL cli_init_redirect(struct cli_state *cli,
fstring ip_name;
struct cli_state cli_redir;
fstring path;
+ vuser_key key;
uint32 len;
char *data;
@@ -2987,6 +2988,9 @@ static BOOL cli_init_redirect(struct cli_state *cli,
prs_struct ps;
uint16 command;
+ key.pid = getpid();
+ key.vuid = UID_FIELD_INVALID;
+
slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid());
if (strequal(srv_name, "*SMBSERVER"))
@@ -3006,7 +3010,7 @@ static BOOL cli_init_redirect(struct cli_state *cli,
command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
if (!create_ntuser_creds(&ps, srv_name, 0x0, command,
- getpid(), usr,
+ &key, usr,
cli->reuse))
{
DEBUG(0,("could not parse credentials\n"));
diff --git a/source/msrpc/msrpcd_process.c b/source/msrpc/msrpcd_process.c
index 0f013935b40..afb4cd1e394 100644
--- a/source/msrpc/msrpcd_process.c
+++ b/source/msrpc/msrpcd_process.c
@@ -211,7 +211,7 @@ static void process_msrpc(msrpc_pipes_struct *p, int c)
/****************************************************************************
reads user credentials from the socket
****************************************************************************/
-BOOL get_user_creds(int c, struct user_creds *usr, uint32 *pid)
+BOOL get_user_creds(int c, struct user_creds *usr, vuser_key *uk)
{
pstring buf;
int rl;
@@ -292,8 +292,8 @@ BOOL get_user_creds(int c, struct user_creds *usr, uint32 *pid)
}
}
- /* obtain the remote process id */
- *pid = cmd.pid;
+ /* obtain the remote process id and vuid */
+ (*uk) = cmd.key;
status = new_con ? 0x0 : 0x1;
@@ -335,48 +335,31 @@ void add_srv_auth_fn(rpcsrv_struct *l, srv_auth_fns *fn)
BOOL msrpcd_init(int c, msrpc_pipes_struct *p)
{
struct user_creds usr;
- gid_t *groups = NULL;
- char *user;
- uint16 vuid;
- uint32 remote_pid;
+ vuser_key uk;
+ user_struct *vuser;
- if (!get_user_creds(c, &usr, &remote_pid))
+ if (!get_user_creds(c, &usr, &uk))
{
DEBUG(0,("authentication failed\n"));
free_user_creds(&usr);
return False;
}
- if (usr.uxs.num_grps != 0)
- {
- int i;
- groups = malloc(usr.uxs.num_grps * sizeof(groups[0]));
- if (groups == NULL)
- {
- return False;
- }
- for (i = 0; i < usr.uxs.num_grps; i++)
- {
- groups[i] = (gid_t)usr.uxs.grps[i];
- }
- }
-
- vuid = create_vuid(usr.uxs.uid, usr.uxs.gid,
- usr.uxs.num_grps, groups,
- usr.uxc.user_name,
- usr.uxc.requested_name,
- usr.uxc.real_name,
- usr.uxc.guest,
- &usr.nts);
-
- if (vuid == UID_FIELD_INVALID)
+ if (uk.vuid == UID_FIELD_INVALID)
{
+ free_user_creds(&usr);
return False;
}
free_user_creds(&usr);
- if (!become_vuser(vuid))
+ if (!become_vuser(&uk))
+ {
+ return False;
+ }
+
+ vuser = get_valid_user_struct(&uk);
+ if (vuser == NULL)
{
return False;
}
@@ -384,17 +367,18 @@ BOOL msrpcd_init(int c, msrpc_pipes_struct *p)
p->l = malloc(sizeof(*p->l));
if (p->l == NULL)
{
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
return False;
}
ZERO_STRUCTP(p->l);
- p->l->vuid = vuid;
- p->l->remote_pid = remote_pid;
+ p->l->key = uk;
- if (!usr.uxc.guest)
+ if (!vuser->guest)
{
- user = usr.uxc.user_name;
+ char *user = vuser->name;
if (!strequal(user,lp_guestaccount(-1)) &&
lp_servicenumber(user) < 0)
{
@@ -408,6 +392,10 @@ BOOL msrpcd_init(int c, msrpc_pipes_struct *p)
}
}
}
+
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+
return True;
}
diff --git a/source/netlogond/srv_netlogon_nt.c b/source/netlogond/srv_netlogon_nt.c
index 88ace14a26c..ddce8d607ef 100644
--- a/source/netlogond/srv_netlogon_nt.c
+++ b/source/netlogond/srv_netlogon_nt.c
@@ -794,7 +794,6 @@ uint32 _net_sam_logon(const DOM_SAM_INFO *sam_id,
DOM_CRED *srv_creds,
uint16 *switch_value,
NET_USER_INFO_3 *user,
- uint32 *auth_resp,
uint16 remote_pid)
{
UNISTR2 *uni_samusr = NULL;
@@ -834,8 +833,6 @@ uint32 _net_sam_logon(const DOM_SAM_INFO *sam_id,
UNISTR2 uni_myname;
UNISTR2 uni_sam_name;
- *auth_resp = 1; /* authoritative response */
-
unistr2_to_ascii(trust_name, &(sam_id->client.login.uni_comp_name),
sizeof(trust_name)-1);
@@ -1013,9 +1010,6 @@ uint32 _net_sam_logon(const DOM_SAM_INFO *sam_id,
/* return the profile plus other bits :-) */
- /* set up pointer indicating user/password failed to be found */
- user->ptr_user_info = 0;
-
make_unistr2(&uni_myname, global_myname, strlen(global_myname));
make_unistr2(&uni_sam_name, global_sam_name, strlen(global_sam_name));
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 3a077555088..a3b7b8a45f6 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -1151,7 +1151,7 @@ convenience routine to grab string parameters into a rotating buffer,
and run standard_sub_basic on them. The buffers can be written to by
callers without affecting the source string.
********************************************************************/
-static char *lp_user_string(uint16 vuid, char *s)
+static char *lp_user_string(const vuser_key *key, char *s)
{
static char *bufs[10];
static int buflen[10];
@@ -1159,6 +1159,7 @@ static char *lp_user_string(uint16 vuid, char *s)
char *ret;
int i;
int len = s?strlen(s):0;
+ user_struct *vuser;
if (next == -1) {
/* initialisation */
@@ -1192,7 +1193,12 @@ static char *lp_user_string(uint16 vuid, char *s)
trim_string(ret, "\"", "\"");
- standard_sub_vuser(get_valid_user_struct(vuid), ret);
+ vuser = get_valid_user_struct(key);
+
+ standard_sub_vuser(vuser, ret);
+
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
return(ret);
}
@@ -1271,7 +1277,7 @@ static char *lp_string(char *s)
int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
#define FN_VUSER_STRING(fn_name,ptr) \
- char *fn_name(uint16 vuid) {return(lp_user_string(vuid, *(char **)(ptr) ? *(char **)(ptr) : ""));}
+ char *fn_name(const vuser_key *key) {return(lp_user_string(key, *(char **)(ptr) ? *(char **)(ptr) : ""));}
struct vfs_options *lp_vfsoptions(int i)
{ return(LP_SNUM_OK(i) ? pSERVICE(i)->vfsOptions : sDefault.vfsOptions); }
diff --git a/source/passdb/smbpassfile.c b/source/passdb/smbpassfile.c
index 42f8cbfbe84..b4f8e6f2eb8 100644
--- a/source/passdb/smbpassfile.c
+++ b/source/passdb/smbpassfile.c
@@ -29,7 +29,8 @@ static FILE *mach_passwd_fp = NULL;
Routine to get the name for a trust account file.
************************************************************************/
-static void get_trust_account_file_name( char *domain, char *name, char *mac_file)
+static void get_trust_account_file_name( const char *domain, const char *name,
+ char *mac_file)
{
unsigned int mac_file_len;
char *p;
@@ -67,7 +68,7 @@ static void get_trust_account_file_name( char *domain, char *name, char *mac_fil
Routine to lock the trust account password file for a domain.
************************************************************************/
-BOOL trust_password_lock( char *domain, char *name, BOOL update)
+BOOL trust_password_lock( const char *domain, const char *name, BOOL update)
{
pstring mac_file;
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 47bf7183304..a892c1280fe 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -51,7 +51,7 @@ Build the print command in the supplied buffer. This means getting the
print command for the service and inserting the printer name and the
print file name. Return NULL on error, else the passed buffer pointer.
****************************************************************************/
-static char *build_print_command(connection_struct *conn, uint16 vuid,
+static char *build_print_command(connection_struct *conn, const vuser_key *key,
int snum,
char *command,
char *syscmd, char *filename1)
@@ -95,7 +95,12 @@ static char *build_print_command(connection_struct *conn, uint16 vuid,
string_sub(syscmd, "%p", tstr);
- standard_sub(conn, get_valid_user_struct(vuid), syscmd);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ }
return (syscmd);
}
@@ -104,7 +109,7 @@ static char *build_print_command(connection_struct *conn, uint16 vuid,
/****************************************************************************
print a file - called on closing the file
****************************************************************************/
-void print_file(connection_struct *conn, uint16 vuid,
+void print_file(connection_struct *conn, const vuser_key *key,
int snum, files_struct *file)
{
pstring syscmd;
@@ -118,7 +123,7 @@ void print_file(connection_struct *conn, uint16 vuid,
return;
}
- tempstr = build_print_command(conn, vuid, snum,
+ tempstr = build_print_command(conn, key, snum,
PRINTCOMMAND(snum),
syscmd, file->fsp_name);
if (tempstr != NULL) {
@@ -961,7 +966,7 @@ static BOOL parse_lpq_entry(int snum,char *line,
/****************************************************************************
get a printer queue
****************************************************************************/
-int get_printqueue(int snum, connection_struct *conn, uint16 vuid,
+int get_printqueue(int snum, connection_struct *conn, const vuser_key *key,
print_queue_struct **queue,
print_status_struct *status)
{
@@ -993,7 +998,12 @@ int get_printqueue(int snum, connection_struct *conn, uint16 vuid,
pstrcpy(syscmd,lpq_command);
string_sub(syscmd,"%p",printername);
- standard_sub(conn, get_valid_user_struct(vuid), syscmd);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ }
slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd));
@@ -1056,7 +1066,7 @@ int get_printqueue(int snum, connection_struct *conn, uint16 vuid,
/****************************************************************************
delete a printer queue entry
****************************************************************************/
-void del_printqueue(connection_struct *conn,uint16 vuid,
+void del_printqueue(connection_struct *conn,const vuser_key *key,
int snum,int jobid)
{
char *lprm_command = lp_lprmcommand(snum);
@@ -1083,7 +1093,12 @@ void del_printqueue(connection_struct *conn,uint16 vuid,
pstrcpy(syscmd,lprm_command);
string_sub(syscmd,"%p",printername);
string_sub(syscmd,"%j",jobstr);
- standard_sub(conn, get_valid_user_struct(vuid), syscmd);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ }
ret = smbrun(syscmd,NULL,False);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -1093,7 +1108,7 @@ void del_printqueue(connection_struct *conn,uint16 vuid,
/****************************************************************************
change status of a printer queue entry
****************************************************************************/
-void status_printjob(connection_struct *conn,uint16 vuid,
+void status_printjob(connection_struct *conn,const vuser_key *key,
int snum,int jobid,int status)
{
char *lpstatus_command =
@@ -1122,7 +1137,12 @@ void status_printjob(connection_struct *conn,uint16 vuid,
pstrcpy(syscmd,lpstatus_command);
string_sub(syscmd,"%p",printername);
string_sub(syscmd,"%j",jobstr);
- standard_sub(conn, get_valid_user_struct(vuid), syscmd);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ }
ret = smbrun(syscmd,NULL,False);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -1154,7 +1174,7 @@ void printjob_decode(int jobid, int *snum, int *job)
/****************************************************************************
Change status of a printer queue
****************************************************************************/
-uint32 status_printqueue(connection_struct *conn,uint16 vuid,
+uint32 status_printqueue(connection_struct *conn,const vuser_key *key,
int snum,int status)
{
char *queuestatus_command = (status==LPSTAT_STOPPED ?
@@ -1177,7 +1197,14 @@ uint32 status_printqueue(connection_struct *conn,uint16 vuid,
pstrcpy(syscmd,queuestatus_command);
string_sub(syscmd,"%p",printername);
- standard_sub(conn, get_valid_user_struct(vuid), syscmd);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ }
+
+
ret = smbrun(syscmd,NULL,False);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
diff --git a/source/rpc_client/cli_connect.c b/source/rpc_client/cli_connect.c
index 6322302c955..aa74954e544 100644
--- a/source/rpc_client/cli_connect.c
+++ b/source/rpc_client/cli_connect.c
@@ -26,6 +26,7 @@
#include "rpc_parse.h"
struct user_creds *usr_creds = NULL;
+vuser_key *key = NULL;
extern int DEBUGLEVEL;
extern pstring scope;
@@ -101,6 +102,7 @@ static struct cli_connection *cli_con_get(const char* srv_name,
BOOL reuse)
{
struct cli_connection *con = NULL;
+ vuser_key con_key;
con = (struct cli_connection*)malloc(sizeof(*con));
@@ -112,6 +114,16 @@ static struct cli_connection *cli_con_get(const char* srv_name,
memset(con, 0, sizeof(*con));
con->type = MSRPC_NONE;
+ if (key != NULL)
+ {
+ con_key = *key;
+ }
+ else
+ {
+ con_key.pid = getpid();
+ con_key.vuid = 1;
+ }
+
copy_user_creds(&con->usr_creds, usr_creds);
con->usr_creds.reuse = reuse;
@@ -142,7 +154,7 @@ static struct cli_connection *cli_con_get(const char* srv_name,
become_root(False);
con->type = MSRPC_LOCAL;
con->usr_creds.reuse = False;
- con->msrpc.local = msrpc_use_add(&pipe_name[6], getpid(),
+ con->msrpc.local = msrpc_use_add(&pipe_name[6], &con_key,
&con->usr_creds,
False);
unbecome_root(False);
@@ -435,7 +447,11 @@ BOOL cli_set_con_usr_sesskey(struct cli_connection *con,
return False;
}
nt = cli_conn_get_ntinfo(con);
- memcpy(nt->usr_sess_key, usr_sess_key, sizeof(nt->usr_sess_key));
+ if (nt != NULL)
+ {
+ memcpy(nt->usr_sess_key, usr_sess_key, sizeof(nt->usr_sess_key));
+ }
+
return True;
}
@@ -526,6 +542,10 @@ struct ntuser_creds *cli_conn_get_usercreds(struct cli_connection *con)
****************************************************************************/
struct ntdom_info * cli_conn_get_ntinfo(struct cli_connection *con)
{
+ if (con == NULL)
+ {
+ return NULL;
+ }
if (con->msrpc.cli == NULL)
{
DEBUG(1,("cli_conn_get_ntinfo: NULL msrpc (closed)\n"));
diff --git a/source/rpc_client/cli_login.c b/source/rpc_client/cli_login.c
index 3e0c37254bf..c9ce7cb372e 100644
--- a/source/rpc_client/cli_login.c
+++ b/source/rpc_client/cli_login.c
@@ -100,14 +100,6 @@ uint32 cli_nt_setup_creds( const char* srv_name,
struct cli_connection *con = NULL;
struct netsec_creds creds;
-#if 0
- if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
- {
- return NT_STATUS_ACCESS_DENIED | 0xC0000000;
- }
- cli_connection_unlink(con);
-#endif
-
safe_strcpy(creds.domain, domain , sizeof(creds.myname)-1);
safe_strcpy(creds.myname, myhostname, sizeof(creds.myname)-1);
memcpy(creds.sess_key, sess_key, sizeof(creds.sess_key));
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index f9d2e3f08f7..68ce16ff653 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -137,7 +137,8 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr,
- caller is expected to free the header data structure once used.
********************************************************************/
-BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, uint8 flags,
+BOOL create_rpc_request(prs_struct *rhdr, uint16 vuid,
+ uint8 op_num, uint8 flags,
int data_len,
int auth_len)
{
@@ -165,7 +166,7 @@ BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, uint8 flags,
data_len, auth_len, alloc_hint));
/* create the rpc request RPC_HDR_REQ */
- make_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
+ make_rpc_hdr_req(&hdr_req, alloc_hint, vuid, op_num);
/* stream-time... */
smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0);
diff --git a/source/rpc_client/cli_pipe_netsec.c b/source/rpc_client/cli_pipe_netsec.c
index b21108e8cca..b745e09d178 100644
--- a/source/rpc_client/cli_pipe_netsec.c
+++ b/source/rpc_client/cli_pipe_netsec.c
@@ -151,7 +151,8 @@ static BOOL create_netsec_pdu(struct cli_connection *con,
data_t.end = data_t.data_size;
data_t.offset = data_t.data_size;
- create_rpc_request(&hdr, op_num, (*flags), frag_len, auth_len);
+ create_rpc_request(&hdr, nt->key.vuid, op_num, (*flags),
+ frag_len, auth_len);
DEBUG(5,("create_netsec_reply: data %d auth %d\n",
data_len, auth_len));
diff --git a/source/rpc_client/cli_pipe_noauth.c b/source/rpc_client/cli_pipe_noauth.c
index 5983f57d6af..6119f1e2ff3 100644
--- a/source/rpc_client/cli_pipe_noauth.c
+++ b/source/rpc_client/cli_pipe_noauth.c
@@ -49,6 +49,7 @@ static BOOL create_noauth_pdu(struct cli_connection *con,
int frag_len;
char *d = prs_data(data, data_start);
struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+
*flags = 0;
data_len = data->offset - data_start;
@@ -79,7 +80,7 @@ static BOOL create_noauth_pdu(struct cli_connection *con,
data_t.end = data_t.data_size;
data_t.offset = data_t.data_size;
- create_rpc_request(&hdr, op_num, (*flags), frag_len, 0);
+ create_rpc_request(&hdr, nt->key.vuid, op_num, (*flags), frag_len, 0);
prs_link(NULL, &hdr , &data_t);
prs_link(&hdr, &data_t, NULL );
diff --git a/source/rpc_client/cli_pipe_ntlmssp.c b/source/rpc_client/cli_pipe_ntlmssp.c
index 3600b3cdd25..ca70dd569a9 100644
--- a/source/rpc_client/cli_pipe_ntlmssp.c
+++ b/source/rpc_client/cli_pipe_ntlmssp.c
@@ -176,7 +176,7 @@ static BOOL create_ntlmssp_pdu(struct cli_connection *con,
return False;
}
- *flags = 0;
+ (*flags) = 0;
auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
NTLMSSP_NEGOTIATE_SIGN);
@@ -214,7 +214,8 @@ static BOOL create_ntlmssp_pdu(struct cli_connection *con,
data_t.end = data_t.data_size;
data_t.offset = data_t.data_size;
- create_rpc_request(&hdr, op_num, (*flags), frag_len, auth_len);
+ create_rpc_request(&hdr, nt->key.vuid, op_num, (*flags),
+ frag_len, auth_len);
if (auth_seal)
{
diff --git a/source/rpc_parse/parse_creds.c b/source/rpc_parse/parse_creds.c
index 3e723787689..29a5bb12f0a 100644
--- a/source/rpc_parse/parse_creds.c
+++ b/source/rpc_parse/parse_creds.c
@@ -412,7 +412,8 @@ BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
prs_uint16("version", ps, depth, &(r_u->version));
prs_uint16("command", ps, depth, &(r_u->command));
- prs_uint32("pid ", ps, depth, &(r_u->pid ));
+
+ vuid_io_key("key", &r_u->key, ps, 0);
prs_string("name ", ps, depth, r_u->name, strlen(r_u->name), sizeof(r_u->name));
prs_align(ps);
@@ -434,7 +435,7 @@ 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,
- uint32 pid,
+ const vuser_key *key,
const struct ntuser_creds *ntu,
BOOL reuse)
{
@@ -452,7 +453,7 @@ BOOL create_ntuser_creds( prs_struct *ps,
fstrcpy(cmd.name, name);
cmd.version = version;
cmd.command = command;
- cmd.pid = pid ;
+ cmd.key = *key ;
cmd.ptr_creds = ntu != NULL ? 1 : 0;
cmd.cred = &usr;
@@ -475,7 +476,7 @@ BOOL create_ntuser_creds( prs_struct *ps,
BOOL create_user_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr)
{
CREDS_CMD cmd;
@@ -488,7 +489,7 @@ BOOL create_user_creds( prs_struct *ps,
fstrcpy(cmd.name, name);
cmd.version = version;
cmd.command = command;
- cmd.pid = pid ;
+ cmd.key = *key;
cmd.ptr_creds = usr != NULL ? 1 : 0;
cmd.cred = usr;
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index e5b4c3dd73f..1204806f977 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -1024,8 +1024,6 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 *usr,
int len_logon_srv = logon_srv != NULL ? logon_srv ->uni_str_len : 0;
int len_logon_dom = logon_dom != NULL ? logon_dom ->uni_str_len : 0;
- usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
-
usr->logon_time = *logon_time;
usr->logoff_time = *logoff_time;
usr->kickoff_time = *kickoff_time;
@@ -1096,6 +1094,8 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 *usr,
make_dom_sid2(&(usr->dom_sid), dom_sid);
/* "other" sids are set up above */
+ usr->auth_resp = 1;
+
return True;
}
@@ -1152,8 +1152,6 @@ BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
int len_logon_srv = strlen(logon_srv);
int len_logon_dom = strlen(logon_dom);
- usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
-
usr->logon_time = *logon_time;
usr->logoff_time = *logoff_time;
usr->kickoff_time = *kickoff_time;
@@ -1224,6 +1222,8 @@ BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
make_dom_sid2(&(usr->dom_sid), dom_sid);
/* "other" sids are set up above */
+ usr->auth_resp = 1;
+
return True;
}
@@ -1242,72 +1242,69 @@ BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int de
prs_align(ps);
- prs_uint32("ptr_user_info ", ps, depth, &(usr->ptr_user_info));
+ smb_io_time("time", &(usr->logon_time) , ps, depth); /* logon time */
+ smb_io_time("time", &(usr->logoff_time) , ps, depth); /* logoff time */
+ smb_io_time("time", &(usr->kickoff_time) , ps, depth); /* kickoff time */
+ smb_io_time("time", &(usr->pass_last_set_time) , ps, depth); /* password last set time */
+ smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
+ smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
+
+ smb_io_unihdr("unihdr", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive unicode string header */
+
+ prs_uint16("logon_count ", ps, depth, &(usr->logon_count )); /* logon count */
+ prs_uint16("bad_pw_count ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
+
+ prs_uint32("user_id ", ps, depth, &(usr->user_id )); /* User ID */
+ prs_uint32("group_id ", ps, depth, &(usr->group_id )); /* Group ID */
+ prs_uint32("num_groups ", ps, depth, &(usr->num_groups )); /* num groups */
+ prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
+ prs_uint32("user_flgs ", ps, depth, &(usr->user_flgs )); /* user flags */
+
+ prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
+
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
+
+ prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
+ prs_uint8s (False, "padding ", ps, depth, usr->padding, 40); /* unused padding bytes? */
+
+ prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
+ prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
+
+ smb_io_unistr2("unistr2", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
- if (usr->ptr_user_info != 0)
+ prs_align(ps);
+ prs_uint32("num_groups2 ", ps, depth, &(usr->num_groups2)); /* num groups */
+ SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
+ for (i = 0; i < usr->num_groups2; i++)
{
- smb_io_time("time", &(usr->logon_time) , ps, depth); /* logon time */
- smb_io_time("time", &(usr->logoff_time) , ps, depth); /* logoff time */
- smb_io_time("time", &(usr->kickoff_time) , ps, depth); /* kickoff time */
- smb_io_time("time", &(usr->pass_last_set_time) , ps, depth); /* password last set time */
- smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
- smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
-
- smb_io_unihdr("unihdr", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
- smb_io_unihdr("unihdr", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
- smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
- smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
- smb_io_unihdr("unihdr", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
- smb_io_unihdr("unihdr", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive unicode string header */
-
- prs_uint16("logon_count ", ps, depth, &(usr->logon_count )); /* logon count */
- prs_uint16("bad_pw_count ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
-
- prs_uint32("user_id ", ps, depth, &(usr->user_id )); /* User ID */
- prs_uint32("group_id ", ps, depth, &(usr->group_id )); /* Group ID */
- prs_uint32("num_groups ", ps, depth, &(usr->num_groups )); /* num groups */
- prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
- prs_uint32("user_flgs ", ps, depth, &(usr->user_flgs )); /* user flags */
-
- prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
-
- smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
- smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
-
- prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
- prs_uint8s (False, "padding ", ps, depth, usr->padding, 40); /* unused padding bytes? */
-
- prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
- prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
-
- smb_io_unistr2("unistr2", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
- smb_io_unistr2("unistr2", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
- smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
- smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
- smb_io_unistr2("unistr2", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
- smb_io_unistr2("unistr2", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
-
- prs_align(ps);
- prs_uint32("num_groups2 ", ps, depth, &(usr->num_groups2)); /* num groups */
- SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
- for (i = 0; i < usr->num_groups2; i++)
- {
- smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
- }
+ smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
+ }
- smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
- smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
+ smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
+ smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
- smb_io_dom_sid2("", &(usr->dom_sid), ps, depth); /* domain SID */
+ smb_io_dom_sid2("", &(usr->dom_sid), ps, depth); /* domain SID */
- SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
+ SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
- for (i = 0; i < usr->num_other_sids; i++)
- {
- smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
- }
+ for (i = 0; i < usr->num_other_sids; i++)
+ {
+ smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
}
+ prs_uint32("auth_resp ", ps, depth, &usr->auth_resp); /* 1 - Authoritative response; 0 - Non-Auth? */
+
return True;
}
@@ -1336,7 +1333,6 @@ BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
const DOM_CRED *srv_creds,
uint16 switch_value,
NET_USER_INFO_3 *user_info,
- uint32 auth_resp,
uint32 status)
{
if (r_s == NULL) return False;
@@ -1353,12 +1349,14 @@ BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
memcpy(&(r_s->srv_creds), srv_creds, sizeof(r_s->srv_creds));
/* store the user information, if there is any. */
r_s->user = user_info;
- if (user_info != NULL && user_info->ptr_user_info != 0)
+ if (user_info != NULL)
{
+ r_s->ptr_user_info = 1;
r_s->switch_value = 3; /* indicates type of validation user info */
}
else
{
+ r_s->ptr_user_info = 0;
r_s->switch_value = 0; /* indicates no info */
}
}
@@ -1367,12 +1365,12 @@ BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
/* XXXX we may want this behaviour:
r_s->buffer_creds = 0;
*/
+ r_s->ptr_user_info = 0;
r_s->switch_value = 0;
r_s->user = NULL;
}
r_s->status = status;
- r_s->auth_resp = auth_resp;
return True;
}
@@ -1392,14 +1390,13 @@ BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int d
prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
prs_align(ps);
+ prs_uint32("ptr_user_info ", ps, depth, &r_l->ptr_user_info);
- if (r_l->switch_value != 0)
+ if (r_l->switch_value != 0 && r_l->ptr_user_info != 0)
{
net_io_user_info3("", r_l->user, ps, depth);
}
- prs_uint32("auth_resp ", ps, depth, &(r_l->auth_resp)); /* 1 - Authoritative response; 0 - Non-Auth? */
-
prs_uint32("status ", ps, depth, &(r_l->status));
prs_align(ps);
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index b56cf5dc665..376a27adfb5 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -903,14 +903,17 @@ BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
{
int i = -1; /* start off at zero after 1st i++ */
+ BOOL len_limited;
+
CHECK_STRUCT(ps);
if (ps->error) return False;
+ len_limited = len == 0 || !ps->io;
+
DEBUG(200,("_prs_string: string %s len %d max %d\n",
str, len, max_buf_size));
DEBUG(10,("%s%04x %s: ", tab_depth(depth), ps->offset, name != NULL ? name : ""));
-
do
{
char *q;
@@ -926,7 +929,7 @@ BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, u
return False;
}
- if (i < len || len == 0)
+ if (i < len || len_limited)
{
RW_CVAL(ps->io, q, str[i], 0);
}
@@ -936,7 +939,7 @@ BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, u
RW_CVAL(ps->io, q, dummy,0);
}
- } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) );
+ } while (i < max_buf_size && (len_limited ? str[i] != 0 : i < len) );
ps->offset += i+1;
diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c
index e0d2d1bba00..167dc5ae0ea 100644
--- a/source/rpc_parse/parse_rpc.c
+++ b/source/rpc_parse/parse_rpc.c
@@ -501,12 +501,13 @@ BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth)
/*******************************************************************
creates an RPC_HDR_REQ structure.
********************************************************************/
-BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum)
+BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 vuid,
+ uint16 opnum)
{
if (hdr == NULL) return False;
hdr->alloc_hint = alloc_hint; /* allocation hint */
- hdr->context_id = 0; /* presentation context identifier */
+ hdr->context_id = vuid; /* presentation context identifier */
hdr->opnum = opnum; /* opnum */
return True;
diff --git a/source/rpc_parse/parse_vuid.c b/source/rpc_parse/parse_vuid.c
new file mode 100644
index 00000000000..fbb011a25eb
--- /dev/null
+++ b/source/rpc_parse/parse_vuid.c
@@ -0,0 +1,150 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tgroupsgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * 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, Cambgroupsge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL vuid_io_key(char *desc, vuser_key *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "vuid_io_key");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("pid ", ps, 0, &r_u->pid);
+ prs_uint16("vuid", ps, 0, &r_u->vuid);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+makes a vuser struct.
+********************************************************************/
+BOOL make_vuid_user_struct(user_struct *r_u,
+ uid_t uid, gid_t gid,
+ const char* name,
+ const char* requested_name,
+ const char* real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t *groups,
+ const NET_USER_INFO_3 *usr)
+{
+ int i;
+
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_user_struct\n"));
+
+ r_u->uid = uid;
+ r_u->gid = gid;
+
+ fstrcpy(r_u->name , name);
+ fstrcpy(r_u->requested_name, requested_name);
+ fstrcpy(r_u->real_name , real_name);
+ r_u->guest = guest;
+
+ r_u->n_groups = n_groups;
+ r_u->groups = (uint32*)Realloc(NULL, sizeof(r_u->groups[0]) *
+ r_u->n_groups);
+ if (r_u->groups == NULL && n_groups != 0)
+ {
+ return False;
+ }
+ for (i = 0; i < n_groups; i++)
+ {
+ r_u->groups[i] = (gid_t)groups[i];
+ }
+
+ memcpy(&r_u->usr, usr, sizeof(r_u->usr));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL vuid_io_user_struct(char *desc, user_struct *r_u, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "vuid_io_user_struct");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("uid", ps, depth, &(r_u->uid));
+ prs_uint32("gid", ps, depth, &(r_u->gid));
+
+ prs_align(ps);
+ prs_string("name", ps, depth, r_u->name, strlen(r_u->name), sizeof(r_u->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));
+
+ prs_uint32("n_groups", ps, depth, &(r_u->n_groups));
+ if (r_u->n_groups != 0)
+ {
+ r_u->groups = (uint32*)Realloc(r_u->groups, sizeof(r_u->groups[0]) *
+ r_u->n_groups);
+ if (r_u->groups == NULL)
+ {
+ vuid_free_user_struct(r_u);
+ return False;
+ }
+ }
+ for (i = 0; i < r_u->n_groups; i++)
+ {
+ prs_uint32("", ps, depth, &(r_u->groups[i]));
+ }
+
+ net_io_user_info3("usr", &r_u->usr, ps, depth);
+
+ return True;
+}
+
+
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void vuid_free_user_struct(user_struct *r_u)
+{
+ if (r_u != NULL && r_u->groups != NULL)
+ {
+ free(r_u->groups);
+ r_u->groups = NULL;
+ }
+}
diff --git a/source/rpc_server/srv_netlog.c b/source/rpc_server/srv_netlog.c
index 1dc6d181003..b4f167a4119 100644
--- a/source/rpc_server/srv_netlog.c
+++ b/source/rpc_server/srv_netlog.c
@@ -51,7 +51,7 @@ static void api_net_req_chal( rpcsrv_struct *p,
net_io_q_req_chal("", &q_r, data, 0);
r_c.status = _net_req_chal(&q_r.uni_logon_srv, &q_r.uni_logon_clnt,
&q_r.clnt_chal, &r_c.srv_chal,
- p->remote_pid); /* strikerXXXX have to pass this parameter */
+ p->key.pid); /* strikerXXXX have to pass this parameter */
/* store the response in the SMB stream */
net_io_r_req_chal("", &r_c, rdata, 0);
@@ -75,7 +75,7 @@ static void api_net_auth( rpcsrv_struct *p,
r_a.status = _net_auth(&q_a.clnt_id,
&q_a.clnt_chal,
&r_a.srv_chal,
- p->remote_pid); /* strikerXXXX have to pass this parameter */
+ p->key.pid); /* strikerXXXX have to pass this parameter */
/* store the response in the SMB stream */
net_io_r_auth("", &r_a, rdata, 0);
@@ -101,7 +101,7 @@ static void api_net_auth_2( rpcsrv_struct *p,
&q_a.clnt_flgs,
&r_a.srv_chal,
&r_a.srv_flgs,
- p->remote_pid); /* strikerXXXX have to pass this parameter */
+ p->key.pid); /* strikerXXXX have to pass this parameter */
/* store the response in the SMB stream */
net_io_r_auth_2("", &r_a, rdata, 0);
@@ -125,7 +125,7 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
r_s.status = _net_srv_pwset(&q_a.clnt_id,
q_a.pwd,
&r_s.srv_cred,
- p->remote_pid); /* strikerXXXX have to pass this parameter */
+ p->key.pid); /* strikerXXXX have to pass this parameter */
/* store the response in the SMB stream */
net_io_r_srv_pwset("", &r_s, rdata, 0);
@@ -155,7 +155,7 @@ static void api_net_sam_logoff( rpcsrv_struct *p,
net_io_q_sam_logoff("", &q_l, data, 0);
status = _net_sam_logoff(&q_l.sam_id,
&srv_cred,
- p->remote_pid); /* strikerXXXX have to pass this parameter */
+ p->key.pid); /* strikerXXXX have to pass this parameter */
make_r_sam_logoff(&r_s, &srv_cred, status);
/* store the response in the SMB stream */
@@ -216,7 +216,7 @@ static void api_net_sam_sync( rpcsrv_struct *p,
/* grab the challenge... */
net_io_q_sam_sync("", &q_s, data, 0);
- status = net_update_creds(p->remote_pid,
+ status = net_update_creds(p->key.pid,
&dc, &q_s.uni_cli_name,
&q_s.cli_creds,
&q_s.ret_creds,
@@ -261,9 +261,9 @@ static void api_net_sam_logon( rpcsrv_struct *p,
DOM_CRED srv_creds;
uint16 switch_value;
NET_USER_INFO_3 info_3;
- uint32 auth_resp;
uint32 status;
+ ZERO_STRUCT(info_3);
ZERO_STRUCT(q_l);
ZERO_STRUCT(r_s);
@@ -274,10 +274,10 @@ static void api_net_sam_logon( rpcsrv_struct *p,
&srv_creds,
&switch_value,
&info_3,
- &auth_resp,
- p->remote_pid);
- make_r_sam_logon(&r_s, &srv_creds, switch_value, &info_3,
- auth_resp, status);
+ p->key.pid);
+ make_r_sam_logon(&r_s, &srv_creds, switch_value,
+ status == NT_STATUS_NOPROBLEMO ? &info_3 : NULL,
+ status);
/* store the response in the SMB stream */
net_io_r_sam_logon("", &r_s, rdata, 0);
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 43c86bd8cdf..1eb7595d70f 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -85,7 +85,8 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
pipes_struct *p;
static int next_pipe;
struct msrpc_state *m = NULL;
- user_struct *vuser = get_valid_user_struct(vuid);
+ vuser_key key = { conn->smbd_pid, vuid };
+ user_struct *vuser = get_valid_user_struct(&key);
struct user_creds usr;
ZERO_STRUCT(usr);
@@ -139,7 +140,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
}
become_root(False); /* to make pipe connection */
- m = msrpc_use_add(pipe_name, getpid(), &usr, False);
+ m = msrpc_use_add(pipe_name, &key, &usr, False);
unbecome_root(False);
if (m == NULL)
diff --git a/source/rpc_server/srv_pipe_netsec.c b/source/rpc_server/srv_pipe_netsec.c
index 55eaaaf7a2a..33534502236 100644
--- a/source/rpc_server/srv_pipe_netsec.c
+++ b/source/rpc_server/srv_pipe_netsec.c
@@ -178,7 +178,7 @@ static BOOL api_netsec_verify(rpcsrv_struct *l)
/*
* obtain the session key
*/
- if (!cred_get(l->remote_pid,
+ if (!cred_get(l->key.pid,
a->netsec_neg.domain, a->netsec_neg.myname, &dc))
{
return False;
diff --git a/source/rpc_server/srv_pipe_ntlmssp.c b/source/rpc_server/srv_pipe_ntlmssp.c
index e9735150e07..3ab40403692 100644
--- a/source/rpc_server/srv_pipe_ntlmssp.c
+++ b/source/rpc_server/srv_pipe_ntlmssp.c
@@ -305,16 +305,17 @@ static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
if (l->auth_validated)
{
become_root(False);
- l->vuid = register_vuid(pw->pw_uid, pw->pw_gid,
+ l->key.pid = getpid();
+ l->key.vuid = register_vuid(l->key.pid, pw->pw_uid, pw->pw_gid,
unix_user, nt_user,
guest, &info3);
unbecome_root(False);
- l->auth_validated = l->vuid != UID_FIELD_INVALID;
+ l->auth_validated = l->key.vuid != UID_FIELD_INVALID;
}
if (l->auth_validated)
{
- l->auth_validated = become_vuser(l->vuid);
+ l->auth_validated = become_vuser(&l->key);
}
if (l->auth_validated)
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
index b8dcd35080b..e3c94905ae5 100644
--- a/source/script/mkproto.awk
+++ b/source/script/mkproto.awk
@@ -46,7 +46,7 @@ END {
/^FN_VUSER_STRING/ {
split($0,a,"[,()]")
- printf "char *%s(uint16 );\n", a[2]
+ printf "char *%s(const vuser_key* );\n", a[2]
}
/^FN_LOCAL_BOOL/ {
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 84387bd178d..37b71f9b159 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1,12 +1,14 @@
-/*
+ /*
Unix SMB/Netbios implementation.
Version 1.9.
Inter-process communication and named pipe handling
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Tridgell 1992-2000
SMB Version handling
- Copyright (C) John H Terpstra 1995-1998
-
+ Copyright (C) John H Terpstra 1995-2000
+
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
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
@@ -73,17 +75,21 @@ static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *
int *rdata_len,int *rparam_len);
-static int CopyExpanded(connection_struct *conn, uint16 vuid,
+static int CopyExpanded(connection_struct *conn, const vuser_key *key,
int snum, char** dst, char* src, int* n)
{
pstring buf;
int l;
+ user_struct *vuser;
if (!src || !dst || !n || !(*dst)) return(0);
StrnCpy(buf,src,sizeof(buf)/2);
string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(conn,get_valid_user_struct(vuid), buf);
+ vuser = get_valid_user_struct(key);
+ standard_sub(conn,vuser, buf);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
StrnCpy(*dst,buf,*n);
l = strlen(*dst) + 1;
(*dst) += l;
@@ -103,23 +109,29 @@ static int CopyAndAdvance(char** dst, char* src, int* n)
}
static int StrlenExpanded(connection_struct *conn,
- uint16 vuid, int snum, char* s)
+ const vuser_key *key, int snum, char* s)
{
+ user_struct *vuser;
pstring buf;
if (!s) return(0);
StrnCpy(buf,s,sizeof(buf)/2);
string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(conn,get_valid_user_struct(vuid), buf);
+ vuser = get_valid_user_struct(key);
+ standard_sub(conn,vuser, buf);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
return strlen(buf) + 1;
}
-static char* Expand(connection_struct *conn, uint16 vuid, int snum, char* s)
+static char* Expand(connection_struct *conn, const vuser_key *key, int snum, char* s)
{
+ user_struct *vuser;
static pstring buf;
if (!s) return(NULL);
StrnCpy(buf,s,sizeof(buf)/2);
string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(conn,get_valid_user_struct(vuid), buf);
+ vuser = get_valid_user_struct(key);
+ standard_sub(conn,vuser, buf);
return &buf[0];
}
@@ -446,7 +458,7 @@ static void fill_printjob_info(connection_struct *conn,
}
}
-static void fill_printq_info(connection_struct *conn, uint16 vuid,
+static void fill_printq_info(connection_struct *conn, const vuser_key *key,
int snum, int uLevel,
struct pack_desc* desc,
int count, print_queue_struct* queue,
@@ -460,7 +472,7 @@ static void fill_printq_info(connection_struct *conn, uint16 vuid,
case 3:
case 4:
case 5:
- PACKS(desc,"z",Expand(conn,vuid, snum,SERVICE(snum)));
+ PACKS(desc,"z",Expand(conn,key, snum,SERVICE(snum)));
break;
}
@@ -478,7 +490,7 @@ static void fill_printq_info(connection_struct *conn, uint16 vuid,
PACKI(desc,"W",LPSTAT_ERROR);
}
else if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(conn,vuid, snum,lp_comment(snum)));
+ PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum)));
PACKI(desc,"W",LPSTAT_OK); /* status */
} else {
PACKS(desc,"z",status->message);
@@ -495,7 +507,7 @@ static void fill_printq_info(connection_struct *conn, uint16 vuid,
PACKS(desc,"z","WinPrint"); /* pszPrProc */
PACKS(desc,"z",""); /* pszParms */
if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(conn,vuid, snum,lp_comment(snum))); /* pszComment */
+ PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum))); /* pszComment */
PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
} else {
PACKS(desc,"z",status->message); /* pszComment */
@@ -686,6 +698,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
+ vuser_key key = { conn->smbd_pid, vuid };
bzero(&status,sizeof(status));
bzero(&desc,sizeof(desc));
@@ -718,7 +731,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
count = get_printerdrivernumber(snum);
DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
} else {
- count = get_printqueue(snum, conn,vuid,&queue,&status);
+ count = get_printqueue(snum, conn,&key,&queue,&status);
}
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
@@ -726,7 +739,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
desc.buflen = mdrcnt;
if (init_package(&desc,1,count)) {
desc.subcount = count;
- fill_printq_info(conn,vuid,snum,uLevel,&desc,count,queue,&status);
+ fill_printq_info(conn,&key,snum,uLevel,&desc,count,queue,&status);
} else if (uLevel == 0) {
/*
* This is a *disgusting* hack.
@@ -785,6 +798,7 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
print_status_struct *status = NULL;
int* subcntarr = NULL;
int queuecnt, subcnt=0, succnt=0;
+ vuser_key key = { conn->smbd_pid, vuid };
bzero(&desc,sizeof(desc));
@@ -816,7 +830,7 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
n = 0;
for (i = 0; i < services; i++)
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- subcntarr[n] = get_printqueue(i, conn, vuid, &queue[n],&status[n]);
+ subcntarr[n] = get_printqueue(i, conn, &key, &queue[n],&status[n]);
subcnt += subcntarr[n];
n++;
}
@@ -830,7 +844,7 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
succnt = 0;
for (i = 0; i < services; i++)
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printq_info(conn,vuid, i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
+ fill_printq_info(conn,&key, i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
n++;
if (desc.errcode == NERR_Success) succnt = n;
}
@@ -1269,7 +1283,7 @@ static BOOL check_share_info(int uLevel, char* id)
return True;
}
-static int fill_share_info(connection_struct *conn, uint16 vuid,
+static int fill_share_info(connection_struct *conn, const vuser_key *key,
int snum, int uLevel,
char** buf, int* buflen,
char** stringbuf, int* stringspace, char* baseaddr)
@@ -1292,7 +1306,7 @@ static int fill_share_info(connection_struct *conn, uint16 vuid,
if (!buf)
{
len = 0;
- if (uLevel > 0) len += StrlenExpanded(conn,vuid,snum,lp_comment(snum));
+ if (uLevel > 0) len += StrlenExpanded(conn,key,snum,lp_comment(snum));
if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
if (buflen) *buflen = struct_len;
if (stringspace) *stringspace = len;
@@ -1325,7 +1339,7 @@ static int fill_share_info(connection_struct *conn, uint16 vuid,
if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
SSVAL(p,14,type); /* device type */
SIVAL(p,16,PTR_DIFF(p2,baseaddr));
- len += CopyExpanded(conn,vuid, snum,&p2,lp_comment(snum),&l2);
+ len += CopyExpanded(conn,key, snum,&p2,lp_comment(snum),&l2);
}
if (uLevel > 1)
@@ -1376,6 +1390,7 @@ static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *para
char *p = skip_string(netname,1);
int uLevel = SVAL(p,0);
int snum = find_service(netname);
+ vuser_key key = { conn->smbd_pid, vuid };
if (snum < 0) return False;
@@ -1385,7 +1400,7 @@ static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *para
*rdata = REALLOC(*rdata,mdrcnt);
p = *rdata;
- *rdata_len = fill_share_info(conn,vuid,snum,uLevel,&p,&mdrcnt,0,0,0);
+ *rdata_len = fill_share_info(conn,&key,snum,uLevel,&p,&mdrcnt,0,0,0);
if (*rdata_len < 0) return False;
*rparam_len = 6;
@@ -1417,6 +1432,7 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
int i;
int data_len, fixed_len, string_len;
int f_len = 0, s_len = 0;
+ vuser_key key = { conn->smbd_pid, vuid };
if (!prefix_ok(str1,"WrLeh")) return False;
if (!check_share_info(uLevel,str2)) return False;
@@ -1426,7 +1442,7 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
if (lp_browseable(i) && lp_snum_ok(i))
{
total++;
- data_len += fill_share_info(conn,vuid,i,uLevel,0,&f_len,0,&s_len,0);
+ data_len += fill_share_info(conn,&key,i,uLevel,0,&f_len,0,&s_len,0);
if (data_len <= buf_len)
{
counted++;
@@ -1446,7 +1462,7 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
s_len = string_len;
for (i = 0; i < count;i++)
if (lp_browseable(i) && lp_snum_ok(i))
- if (fill_share_info(conn,vuid,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
+ if (fill_share_info(conn,&key,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
break;
*rparam_len = 8;
@@ -1659,6 +1675,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
char *p = skip_string(str2,1);
int jobid, snum;
int i, count;
+ vuser_key key = { conn->smbd_pid, vuid };
printjob_decode(SVAL(p,0), &snum, &jobid);
@@ -1677,7 +1694,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
{
print_queue_struct *queue=NULL;
lpq_reset(snum);
- count = get_printqueue(snum,conn,vuid,&queue,NULL);
+ count = get_printqueue(snum,conn,&key,&queue,NULL);
for (i=0;i<count;i++)
if ((queue[i].job&0xFF) == jobid)
@@ -1685,13 +1702,13 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
switch (function) {
case 81: /* delete */
DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
- del_printqueue(conn,vuid,snum,queue[i].job);
+ del_printqueue(conn,&key,snum,queue[i].job);
break;
case 82: /* pause */
case 83: /* resume */
DEBUG(3,("%s queue entry %d\n",
(function==82?"pausing":"resuming"),queue[i].job));
- status_printjob(conn,vuid,snum,queue[i].job,
+ status_printjob(conn,&key,snum,queue[i].job,
(function==82?LPQ_PAUSED:LPQ_QUEUED));
break;
}
@@ -1722,6 +1739,7 @@ static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *para
char *str2 = skip_string(str1,1);
char *QueueName = skip_string(str2,1);
int snum;
+ vuser_key key = { conn->smbd_pid, vuid };
/* check it's a supported varient */
if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
@@ -1750,17 +1768,19 @@ static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *para
switch (function) {
case 74: /* Pause queue */
case 75: /* Resume queue */
- status_printqueue(conn,vuid,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
+ {
+ status_printqueue(conn,&key,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
DEBUG(3,("Print queue %s, queue=%s\n",
(function==74?"pause":"resume"),QueueName));
break;
+ }
case 103: /* Purge */
{
print_queue_struct *queue=NULL;
int i, count;
- count = get_printqueue(snum,conn,vuid,&queue,NULL);
+ count = get_printqueue(snum,conn,&key,&queue,NULL);
for (i = 0; i < count; i++)
- del_printqueue(conn,vuid,snum,queue[i].job);
+ del_printqueue(conn,&key,snum,queue[i].job);
if (queue) free(queue);
DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
@@ -1810,6 +1830,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
int i;
char *s = data;
files_struct *fsp;
+ vuser_key key = { conn->smbd_pid, vuid };
printjob_decode(SVAL(p,0), &snum, &jobid);
@@ -1831,7 +1852,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
int count;
lpq_reset(snum);
- count = get_printqueue(snum,conn,vuid,&queue,NULL);
+ count = get_printqueue(snum,conn,&key,&queue,NULL);
for (i=0;i<count;i++) /* find job */
if ((queue[i].job&0xFF) == jobid) break;
@@ -1916,6 +1937,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
int uLevel = SVAL(p,0);
char *p2;
int struct_len;
+ vuser_key key = { conn->smbd_pid, vuid };
DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
@@ -1987,10 +2009,14 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
if (mdrcnt == struct_len) {
SIVAL(p,6,0);
} else {
+ user_struct *vuser = get_valid_user_struct(&key);
SIVAL(p,6,PTR_DIFF(p2,*rdata));
- standard_sub(conn,get_valid_user_struct(vuid), comment);
+ standard_sub(conn,vuser, comment);
StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
p2 = skip_string(p2,1);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+
}
}
if (uLevel > 1)
@@ -2261,11 +2287,12 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
char *p = skip_string(UserName,1);
int uLevel = SVAL(p,0);
char *p2;
+ vuser_key key = { conn->smbd_pid, vuid };
/* get NIS home of a previously validated user - simeon */
/* With share level security vuid will always be zero.
Don't depend on vuser being non-null !!. JRA */
- user_struct *vuser = get_valid_user_struct(vuid);
+ user_struct *vuser = get_valid_user_struct(&key);
if (vuser != NULL)
DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid, vuser->name));
@@ -2283,10 +2310,20 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
case 10: p2 = "B21Bzzz"; break;
case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
- default: return False;
+ default:
+ {
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ return False;
+ }
}
- if (strcmp(p2,str2) != 0) return False;
+ if (strcmp(p2,str2) != 0)
+ {
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ return False;
+ }
*rdata_len = mdrcnt + 1024;
*rdata = REALLOC(*rdata,*rdata_len);
@@ -2327,7 +2364,7 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
SIVALS(p,usri11_password_age,-1); /* password age */
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
- pstrcpy(p2, lp_logon_path(vuid));
+ pstrcpy(p2, lp_logon_path(&key));
p2 = skip_string(p2,1);
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
pstrcpy(p2,"");
@@ -2363,7 +2400,7 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVAL(p,42,
conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- pstrcpy(p2,lp_logon_path(vuid));
+ pstrcpy(p2,lp_logon_path(&key));
p2 = skip_string(p2,1);
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
*p2++ = 0;
@@ -2403,6 +2440,9 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVAL(*rparam,4,*rdata_len); /* is this right?? */
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+
return(True);
}
@@ -2468,6 +2508,7 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
struct pack_desc desc;
char* name;
char* logon_script;
+ vuser_key key = { conn->smbd_pid, vuid };
uLevel = SVAL(p,0);
name = p + 2;
@@ -2487,6 +2528,7 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
if (init_package(&desc,1,0))
{
+ user_struct *vuser = get_valid_user_struct(&key);
PACKI(&desc,"W",0); /* code */
PACKS(&desc,"B21",name); /* eff. name */
PACKS(&desc,"B",""); /* pad */
@@ -2513,8 +2555,10 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
/* JHT - By calling lp_logon_script() and standard_sub() we have */
/* made sure all macros are fully substituted and available */
- logon_script = lp_logon_script(vuid);
- standard_sub( conn, get_valid_user_struct(vuid), logon_script );
+ logon_script = lp_logon_script(&key);
+ standard_sub( conn, vuser, logon_script );
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
PACKS(&desc,"z", logon_script); /* script path */
/* End of JHT mods */
@@ -2580,6 +2624,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
+ vuser_key key = { conn->smbd_pid, vuid };
uLevel = SVAL(p,2);
@@ -2596,7 +2641,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
if (snum < 0 || !VALID_SNUM(snum)) return(False);
- count = get_printqueue(snum,conn,vuid,&queue,&status);
+ count = get_printqueue(snum,conn,&key,&queue,&status);
for (i = 0; i < count; i++) {
if ((queue[i].job & 0xFF) == job) break;
}
@@ -2643,6 +2688,7 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
+ vuser_key key = { conn->smbd_pid, vuid };
bzero(&desc,sizeof(desc));
bzero(&status,sizeof(status));
@@ -2668,7 +2714,7 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
if (snum < 0 || !VALID_SNUM(snum)) return(False);
- count = get_printqueue(snum,conn,vuid,&queue,&status);
+ count = get_printqueue(snum,conn,&key,&queue,&status);
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
desc.base = *rdata;
desc.buflen = mdrcnt;
diff --git a/source/smbd/open.c b/source/smbd/open.c
index fe20d95ef8b..7608a25d80f 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -501,7 +501,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
conn->num_files_open++;
fsp->mode = sbuf->st_mode;
GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_user.vuid;
+ fsp->vuid = current_user.key.vuid;
fsp->size = 0;
fsp->pos = -1;
fsp->open = True;
@@ -1063,7 +1063,7 @@ int open_directory(files_struct *fsp,connection_struct *conn,
conn->num_files_open++;
fsp->mode = 0;
GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_user.vuid;
+ fsp->vuid = current_user.key.vuid;
fsp->size = 0;
fsp->pos = -1;
fsp->open = True;
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 99fe7a69fab..1850c8c9d9a 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -697,7 +697,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
* user, then unbecome the user whilst we're doing this.
*/
saved_conn = fsp->conn;
- saved_vuid = current_user.vuid;
+ saved_vuid = current_user.key.vuid;
dos_GetWd(saved_dir);
unbecome_user();
/* Save the chain fnum. */
diff --git a/source/smbd/password.c b/source/smbd/password.c
index 2141525bc09..005e36c9b85 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -192,16 +192,18 @@ static char *validate_group(char *group,char *password,int pwlen,int snum,
/****************************************************************************
check for authority to login to a service with a given username/password
****************************************************************************/
-BOOL authorise_login(int snum,char *user, char *domain,
+BOOL authorise_login(int snum, char *user, char *domain,
char *password, int pwlen,
- BOOL *guest,BOOL *force,uint16 vuid)
+ BOOL *guest,BOOL *force,
+ const vuser_key *key)
{
- BOOL ok = False;
-
- *guest = False;
-
+ BOOL ok = False;
+
+ DEBUG(0,("authorise_login: TODO. split function, it's 6 levels!\n"));
+ *guest = False;
+
#if DEBUG_PASSWORD
- DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
+ DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
#endif
/* there are several possibilities:
@@ -216,136 +218,154 @@ BOOL authorise_login(int snum,char *user, char *domain,
if the service is guest_only then steps 1 to 5 are skipped
*/
- if (GUEST_ONLY(snum)) *force = True;
-
- if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
- {
+ if (GUEST_ONLY(snum)) *force = True;
- user_struct *vuser = get_valid_user_struct(vuid);
-
- /* check the given username and password */
- if (!ok && (*user) && user_ok(user,snum)) {
- ok = password_ok(user,domain, password, pwlen, NULL, 0, NULL, &vuser->usr);
- if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
- }
+ if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
+ {
+ user_struct *vuser = get_valid_user_struct(key);
- /* check for a previously registered guest username */
- if (!ok && (vuser != 0) && vuser->guest) {
- if (user_ok(vuser->name,snum) &&
- password_ok(vuser->name, domain, password, pwlen, NULL, 0, NULL, &vuser->usr)) {
- fstrcpy(user, vuser->name);
- vuser->guest = False;
- DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
- ok = True;
- }
- }
+ /* check the given username and password */
+ if (!ok && (*user) && user_ok(user,snum))
+ {
+ ok = password_ok(user,domain, password, pwlen, NULL, 0, NULL, &vuser->usr);
+ if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
+ }
+ /* check for a previously registered guest username */
+ if (!ok && (vuser != 0) && vuser->guest)
+ {
+ if (user_ok(vuser->name,snum) &&
+ password_ok(vuser->name, domain, password, pwlen, NULL, 0, NULL, &vuser->usr))
+ {
+ fstrcpy(user, vuser->name);
+ vuser->guest = False;
+ DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
+ ok = True;
+ }
+ }
- /* now check the list of session users */
- if (!ok)
- {
- char *auser;
- char *user_list = strdup(session_users);
- if (!user_list) return False;
- for (auser=strtok(user_list,LIST_SEP);
- !ok && auser;
- auser = strtok(NULL,LIST_SEP))
- {
- fstring user2;
- fstrcpy(user2,auser);
- if (!user_ok(user2,snum)) continue;
-
- if (password_ok(user2, domain, password, pwlen, NULL, 0, NULL,
- &vuser->usr))
- {
- ok = True;
- fstrcpy(user,user2);
- DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
- }
- }
- free(user_list);
- }
+ /* now check the list of session users */
+ if (!ok)
+ {
+ char *auser;
+ char *user_list = strdup(session_users);
+ if (!user_list)
+ {
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ return False;
+ }
+
+ for (auser=strtok(user_list,LIST_SEP);
+ !ok && auser;
+ auser = strtok(NULL,LIST_SEP))
+ {
+ fstring user2;
+ fstrcpy(user2,auser);
+ if (!user_ok(user2,snum)) continue;
+
+ if (password_ok(user2, domain, password, pwlen, NULL, 0, NULL,
+ &vuser->usr))
+ {
+ ok = True;
+ fstrcpy(user,user2);
+ DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
+ }
+ }
+ free(user_list);
+ }
- /* check for a previously validated username/password pair */
- if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) &&
- (vuser != 0) && !vuser->guest &&
- user_ok(vuser->name,snum)) {
- fstrcpy(user,vuser->name);
- *guest = False;
- DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
- ok = True;
- }
+ /* check for a previously validated username/password pair */
+ if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) &&
+ (vuser != 0) && !vuser->guest &&
+ user_ok(vuser->name,snum))
+ {
+ fstrcpy(user,vuser->name);
+ *guest = False;
+ DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
+ ok = True;
+ }
- /* check for a rhosts entry */
- if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) {
- ok = True;
- DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
- }
+ /* check for a rhosts entry */
+ if (!ok && user_ok(user,snum) && check_hosts_equiv(user))
+ {
+ ok = True;
+ DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
+ }
- /* check the user= fields and the given password */
- if (!ok && lp_username(snum)) {
- char *auser;
- pstring user_list;
- StrnCpy(user_list,lp_username(snum),sizeof(pstring));
+ /* check the user= fields and the given password */
+ if (!ok && lp_username(snum))
+ {
+ char *auser;
+ pstring user_list;
+ StrnCpy(user_list,lp_username(snum),sizeof(pstring));
+
+ string_sub(user_list,"%S",lp_servicename(snum));
+
+ for (auser=strtok(user_list,LIST_SEP);
+ auser && !ok;
+ auser = strtok(NULL,LIST_SEP))
+ {
+ if (*auser == '@')
+ {
+ auser = validate_group(auser+1,password,pwlen,snum, &vuser->usr);
+ if (auser)
+ {
+ ok = True;
+ fstrcpy(user,auser);
+ DEBUG(3,("ACCEPTED: group username and given password ok\n"));
+ }
+ }
+ else
+ {
+ fstring user2;
+ fstrcpy(user2,auser);
+ if (user_ok(user2,snum) &&
+ password_ok(user2,domain,password,pwlen,NULL, 0,
+ NULL, &vuser->usr))
+ {
+ ok = True;
+ fstrcpy(user,user2);
+ DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
+ }
+ }
+ }
+ }
+
+ if (vuser != NULL)
+ {
+ tdb_store_vuid(key, vuser);
+ }
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
- string_sub(user_list,"%S",lp_servicename(snum));
-
- for (auser=strtok(user_list,LIST_SEP);
- auser && !ok;
- auser = strtok(NULL,LIST_SEP))
- {
- if (*auser == '@')
- {
- auser = validate_group(auser+1,password,pwlen,snum, &vuser->usr);
- if (auser)
- {
- ok = True;
- fstrcpy(user,auser);
- DEBUG(3,("ACCEPTED: group username and given password ok\n"));
- }
- }
- else
- {
- fstring user2;
- fstrcpy(user2,auser);
- if (user_ok(user2,snum) &&
- password_ok(user2,domain,password,pwlen,NULL, 0,
- NULL, &vuser->usr))
- {
- ok = True;
- fstrcpy(user,user2);
- DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
- }
- }
- }
- }
- } /* not guest only */
+ } /* not guest only */
- /* check for a normal guest connection */
- if (!ok && GUEST_OK(snum))
- {
- fstring guestname;
- StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
- if (Get_Pwnam(guestname,True))
+ /* check for a normal guest connection */
+ if (!ok && GUEST_OK(snum))
{
- fstrcpy(user,guestname);
- ok = True;
- DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
+ fstring guestname;
+ StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
+ if (Get_Pwnam(guestname,True))
+ {
+ fstrcpy(user,guestname);
+ ok = True;
+ DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
+ }
+ else
+ DEBUG(0,("Invalid guest account %s??\n",guestname));
+ *guest = True;
+ *force = True;
}
- else
- DEBUG(0,("Invalid guest account %s??\n",guestname));
- *guest = True;
- *force = True;
- }
- if (ok && !user_ok(user,snum))
- {
- DEBUG(0,("rejected invalid user %s\n",user));
- ok = False;
- }
+ if (ok && !user_ok(user,snum))
+ {
+ DEBUG(0,("rejected invalid user %s\n",user));
+ ok = False;
+ }
- return(ok);
+ return(ok);
}
diff --git a/source/smbd/process.c b/source/smbd/process.c
index d391914f600..e95135a484a 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -435,14 +435,20 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
* move it unless you know what you're doing... :-).
* JRA.
*/
- if (session_tag != last_session_tag) {
+ if (session_tag != last_session_tag)
+ {
user_struct *vuser = NULL;
+ vuser_key key = { pid, session_tag };
last_session_tag = session_tag;
if(session_tag != UID_FIELD_INVALID)
- vuser = get_valid_user_struct(session_tag);
+ vuser = get_valid_user_struct(&key);
if(vuser != NULL)
+ {
pstrcpy( sesssetup_user, vuser->requested_name);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+ }
}
/* does this protocol need to be run as root? */
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index cee776351a6..51842b9462f 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -384,6 +384,7 @@ static int session_trust_account(connection_struct *conn,
if (last_challenge(last_chal))
{
NET_USER_INFO_3 info3;
+ ZERO_STRUCT(info3);
status = check_domain_security(user, domain,
last_chal,
(uchar *)smb_passwd, smb_passlen,
@@ -426,6 +427,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
BOOL doencrypt = SMBENCRYPT();
char *domain = "";
+ ZERO_STRUCT(info3);
+
*smb_apasswd = 0;
*smb_ntpasswd = 0;
@@ -693,7 +696,7 @@ user %s attempted down-level SMB connection\n", user));
/* register the name and uid as being validated, so further connections
to a uid can get through without a password, on the same VC */
- sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest,&info3);
+ sess_vuid = register_vuid(getpid(), uid,gid,user,sesssetup_user,guest,&info3);
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
@@ -1450,9 +1453,14 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
uint16 vuid = SVAL(inbuf,smb_uid);
- user_struct *vuser = get_valid_user_struct(vuid);
+ vuser_key key;
+ user_struct *vuser = NULL;
+ key.pid = conn != NULL ? conn->smbd_pid : getpid();
+ key.vuid = vuid;
+ vuser = get_valid_user_struct(&key);
- if(vuser == 0) {
+ if (vuser == 0)
+ {
DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
}
@@ -1462,7 +1470,7 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,
file_close_user(vuid);
}
- invalidate_vuid(vuid);
+ invalidate_vuid(&key);
set_message(outbuf,2,0,True);
@@ -2764,6 +2772,7 @@ int reply_printqueue(connection_struct *conn,
int max_count = SVAL(inbuf,smb_vwv0);
int start_index = SVAL(inbuf,smb_vwv1);
uint16 vuid = SVAL(inbuf,smb_uid);
+ vuser_key key = { conn->smbd_pid, vuid };
/* we used to allow the client to get the cnum wrong, but that
is really quite gross and only worked when there was only
@@ -2783,7 +2792,7 @@ int reply_printqueue(connection_struct *conn,
{
print_queue_struct *queue = NULL;
char *p = smb_buf(outbuf) + 3;
- int count = get_printqueue(SNUM(conn), conn, vuid, &queue,NULL);
+ int count = get_printqueue(SNUM(conn), conn, &key, &queue,NULL);
int num_to_get = ABS(max_count);
int first = (max_count>0?start_index:start_index+max_count+1);
int i;
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 8a0ba725b09..a251cfcfa63 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -202,6 +202,10 @@ connection_struct *make_connection(char *service,char *user,
BOOL force = False;
extern int Client;
connection_struct *conn;
+ vuser_key key;
+
+ key.pid = getpid();
+ key.vuid = vuid;
strlower(service);
@@ -224,9 +228,12 @@ connection_struct *make_connection(char *service,char *user,
return(make_connection(user,user,domain,password,
pwlen,dev,vuid,ecode));
- if(lp_security() != SEC_SHARE) {
- if (validated_username(vuid)) {
- pstrcpy(user,validated_username(vuid));
+ if(lp_security() != SEC_SHARE)
+ {
+ fstring user_name;
+ if (validated_username(&key, user_name, sizeof(user_name)))
+ {
+ pstrcpy(user, user_name);
return(make_connection(user,user,domain,password,pwlen,dev,vuid,ecode));
}
} else {
@@ -273,7 +280,7 @@ connection_struct *make_connection(char *service,char *user,
add_session_user(service);
/* shall we let them in? */
- if (!authorise_login(snum,user,domain,password,pwlen,&guest,&force,vuid))
+ if (!authorise_login(snum,user,domain,password,pwlen,&guest,&force,&key))
{
DEBUG( 2, ( "Invalid username/password for %s\n", service ) );
*ecode = ERRbadpw;
@@ -411,8 +418,11 @@ connection_struct *make_connection(char *service,char *user,
{
pstring s;
+ user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(s,lp_pathname(snum));
- standard_sub(conn,get_valid_user_struct(vuid), s);
+ standard_sub(conn,vuser, s);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
string_set(&conn->connectpath,s);
DEBUG(3,("Connect path is %s\n",s));
}
@@ -444,10 +454,14 @@ connection_struct *make_connection(char *service,char *user,
} /* IS_IPC */
/* execute any "root preexec = " line */
- if (*lp_rootpreexec(SNUM(conn))) {
+ if (*lp_rootpreexec(SNUM(conn)))
+ {
pstring cmd;
+ user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(cmd,lp_rootpreexec(SNUM(conn)));
- standard_sub(conn,get_valid_user_struct(vuid), cmd);
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
DEBUG(5,("cmd=%s\n",cmd));
smbrun(cmd,NULL,False);
}
@@ -499,10 +513,14 @@ connection_struct *make_connection(char *service,char *user,
add_session_user(user);
/* execute any "preexec = " line */
- if (*lp_preexec(SNUM(conn))) {
+ if (*lp_preexec(SNUM(conn)))
+ {
pstring cmd;
+ user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(cmd,lp_preexec(SNUM(conn)));
- standard_sub(conn,get_valid_user_struct(vuid), cmd);
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
smbrun(cmd,NULL,False);
}
@@ -522,7 +540,7 @@ connection_struct *make_connection(char *service,char *user,
dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)));
dbgtext( "as user %s ", user );
dbgtext( "(uid=%d, gid=%d) ", (int)conn->uid, (int)conn->gid );
- dbgtext( "(pid %d)\n", (int)getpid() );
+ dbgtext( "(pid %d)\n", (int)key.pid );
}
/* Invoke make connection hook */
@@ -576,6 +594,8 @@ close a cnum
****************************************************************************/
void close_cnum(connection_struct *conn, uint16 vuid)
{
+ vuser_key key = { conn->smbd_pid, vuid };
+
DirCacheFlush(SNUM(conn));
unbecome_user();
@@ -612,20 +632,28 @@ void close_cnum(connection_struct *conn, uint16 vuid)
/* execute any "postexec = " line */
if (*lp_postexec(SNUM(conn)) &&
- become_user(conn, vuid)) {
+ become_user(conn, vuid))
+ {
+ user_struct *vuser = get_valid_user_struct(&key);
pstring cmd;
pstrcpy(cmd,lp_postexec(SNUM(conn)));
- standard_sub(conn,get_valid_user_struct(vuid), cmd);
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
smbrun(cmd,NULL,False);
unbecome_user();
}
unbecome_user();
/* execute any "root postexec = " line */
- if (*lp_rootpostexec(SNUM(conn))) {
+ if (*lp_rootpostexec(SNUM(conn)))
+ {
+ user_struct *vuser = get_valid_user_struct(&key);
pstring cmd;
pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
- standard_sub(conn,get_valid_user_struct(vuid), cmd);
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
smbrun(cmd,NULL,False);
}
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index bbaf73eef06..6b05cfda2f4 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -30,7 +30,17 @@ extern struct current_user current_user;
****************************************************************************/
BOOL become_user(connection_struct *conn, uint16 vuid)
{
- user_struct *vuser = get_valid_user_struct(vuid);
+ vuser_key key;
+ key.pid = getpid();
+ key.vuid = vuid;
+ return become_userk(conn, &key);
+}
+/****************************************************************************
+ Become the user of a connection number.
+****************************************************************************/
+BOOL become_userk(connection_struct *conn, const vuser_key *key)
+{
+ user_struct *vuser = NULL;
int snum;
gid_t gid = -1;
uid_t uid = -1;
@@ -55,13 +65,21 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
(current_user.uid == conn->uid))
{
DEBUG(4,("Skipping become_user - already user\n"));
+
return(True);
}
- else if ((current_user.conn == conn) &&
- (vuser != NULL) && (current_user.vuid == vuid) &&
+
+ vuser = get_valid_user_struct(key);
+
+ if ((current_user.conn == conn) &&
+ (vuser != NULL) &&
+ (current_user.key.vuid == key->vuid) &&
+ (current_user.key.pid == key->pid) &&
(current_user.uid == vuser->uid))
{
DEBUG(4,("Skipping become_user - already user\n"));
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
return(True);
}
@@ -70,7 +88,11 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
snum = SNUM(conn);
if((vuser != NULL) && !check_vuser_ok(&conn->uid_cache, vuser, snum))
+ {
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
return False;
+ }
if (conn->force_user ||
lp_security() == SEC_SHARE ||
@@ -81,7 +103,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
ngroups = conn->ngroups;
} else {
if (!vuser) {
- DEBUG(2,("Invalid vuid used %d\n",vuid));
+ DEBUG(2,("Invalid vuid used %d\n",key->vuid));
return(False);
}
uid = vuser->uid;
@@ -118,7 +140,10 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
}
}
- return become_unix_sec_ctx(vuid, conn, uid, gid, ngroups, groups);
+ vuid_free_user_struct(vuser);
+ safe_free(vuser);
+
+ return become_unix_sec_ctx(key, conn, uid, gid, ngroups, groups);
}
/****************************************************************************