From b11e5b1342a4806409eba6438d6121718d6a696a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Apr 2003 16:44:08 +0000 Subject: Don't make installclientlib depend on the shared-linked version of libsmbclient - we need it to work on other platforms as well (This used to be commit 77b1589188ba27b107f11232b7b7df4dea364948) --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 2ba1fa6ecb..913c0b86a4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1132,7 +1132,7 @@ installdat: installdirs installswat: installdirs @$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(SWATDIR) $(srcdir) -installclientlib: bin/libsmbclient.@SHLIBEXT@ +installclientlib: -$(INSTALLCLIENTCMD_SH) bin/libsmbclient.@SHLIBEXT@ $(DESTDIR)${prefix}/lib -$(INSTALLCLIENTCMD_A) bin/libsmbclient.a $(DESTDIR)${prefix}/lib @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)${prefix}/include -- cgit From c2fc81156c74af33d4ad63671fe62ce67889e02f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Apr 2003 17:36:59 +0000 Subject: make installclientlib depend on the shared-linked or statically-linked version of libsmbclient, depending on what is possible - pointed out by Paul Green (This used to be commit 69e37469c4de6c3716ebb65e477009b9f4da54ea) --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 913c0b86a4..33c687fa96 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1132,7 +1132,7 @@ installdat: installdirs installswat: installdirs @$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(SWATDIR) $(srcdir) -installclientlib: +installclientlib: libsmbclient -$(INSTALLCLIENTCMD_SH) bin/libsmbclient.@SHLIBEXT@ $(DESTDIR)${prefix}/lib -$(INSTALLCLIENTCMD_A) bin/libsmbclient.a $(DESTDIR)${prefix}/lib @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)${prefix}/include -- cgit From 31e21b67d998eed46c55132cc6067db6163d30c1 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 7 Apr 2003 18:01:40 +0000 Subject: Decode the PAC! This patch just decodes it and then frees it, so it's just for doc purposes right now (you can see it in the debug logs). (This used to be commit 046c2087a11b9ce7a02aece34ffb129ce0d66b08) --- source3/Makefile.in | 2 +- source3/include/authdata.h | 131 +++++++++++ source3/include/ntdomain.h | 4 +- source3/libads/authdata.c | 495 +++++++++++++++++++++++++++++++++++++++ source3/libads/kerberos_verify.c | 6 + 5 files changed, 636 insertions(+), 2 deletions(-) create mode 100644 source3/include/authdata.h create mode 100644 source3/libads/authdata.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 33c687fa96..fc18fc2ff2 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -195,7 +195,7 @@ LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \ libads/krb5_setpw.o libads/ldap_user.o \ libads/ads_struct.o libads/ads_status.o \ libads/disp_sec.o libads/ads_utils.o libads/ldap_utils.o \ - libads/ads_ldap.o + libads/ads_ldap.o libads/authdata.o LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o diff --git a/source3/include/authdata.h b/source3/include/authdata.h new file mode 100644 index 0000000000..dc9f217549 --- /dev/null +++ b/source3/include/authdata.h @@ -0,0 +1,131 @@ +/* + Unix SMB/CIFS implementation. + Kerberos authorization data + Copyright (C) Jim McDonough 2003 + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _AUTHDATA_H +#define _AUTHDATA_H + +#include "rpc_misc.h" + +#define PAC_TYPE_LOGON_INFO 1 +#define PAC_TYPE_SERVER_CHECKSUM 6 +#define PAC_TYPE_PRIVSVR_CHECKSUM 7 + +typedef struct pac_signature_data { + uint32 type; + uint8 *signature; +} PAC_SIGNATURE_DATA; + +typedef struct krb_sid_and_attrs { + uint32 sid_ptr; + uint32 attrs; + DOM_SID2 *sid; +} KRB_SID_AND_ATTRS; + +typedef struct krb_sid_and_attr_array { + uint32 count; + KRB_SID_AND_ATTRS *krb_sid_and_attrs; +} KRB_SID_AND_ATTR_ARRAY; + + +/* This is awfully similar to a samr_user_info_23, but not identical. + Many of the field names have been swiped from there, because it is + so similar that they are likely the same, but many have been verified. + Some are in a different order, though... */ +typedef struct pac_logon_info { + NTTIME logon_time; /* logon time */ + NTTIME logoff_time; /* logoff time */ + NTTIME kickoff_time; /* kickoff time */ + NTTIME pass_last_set_time; /* password last set time */ + NTTIME pass_can_change_time; /* password can change time */ + NTTIME pass_must_change_time; /* password must change time */ + + UNIHDR hdr_user_name; /* user name unicode string header */ + UNIHDR hdr_full_name; /* user's full name unicode string header */ + UNIHDR hdr_logon_script; /* these last 4 appear to be in a different */ + UNIHDR hdr_profile_path; /* order than in the info23 */ + UNIHDR hdr_home_dir; + UNIHDR hdr_dir_drive; + + uint16 logon_count; /* number of times user has logged onto domain */ + uint16 reserved12; + + uint32 user_rid; + uint32 group_rid; + uint32 group_count; + uint32 group_membership_ptr; + uint32 user_flags; + + uint32 reserved13[4]; + UNIHDR hdr_dom_controller; + UNIHDR hdr_dom_name; + + uint32 ptr_dom_sid; + + uint32 reserved16[2]; + uint32 reserved17; /* looks like it may be acb_info */ + uint32 reserved18[7]; + + uint32 sid_count; + uint32 ptr_extra_sids; + + uint32 ptr_res_group_dom_sid; + uint32 res_group_count; + uint32 ptr_res_group_sids; + + UNISTR2 uni_user_name; /* user name unicode string header */ + UNISTR2 uni_full_name; /* user's full name unicode string header */ + UNISTR2 uni_logon_script; /* these last 4 appear to be in a different*/ + UNISTR2 uni_profile_path; /* order than in the info23 */ + UNISTR2 uni_home_dir; + UNISTR2 uni_dir_drive; + UNISTR2 uni_dom_controller; + UNISTR2 uni_dom_name; + DOM_SID2 dom_sid; + KRB_SID_AND_ATTR_ARRAY extra_sids; + +} PAC_LOGON_INFO; + +typedef struct pac_info_ctr +{ + union + { + PAC_LOGON_INFO *logon_info; + PAC_SIGNATURE_DATA *srv_cksum; + PAC_SIGNATURE_DATA *privsrv_cksum; + } pac; +} PAC_INFO_CTR; + +typedef struct pac_info_hdr { + uint32 type; + uint32 size; + uint32 offset; + uint32 offsethi; + PAC_INFO_CTR *ctr; +} PAC_INFO_HDR; + +typedef struct pac_data { + uint32 num_buffers; + uint32 version; + PAC_INFO_HDR *pac_info_hdr_ptr; +} PAC_DATA; + + +#endif diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index d02195b378..9216640c03 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -372,6 +372,9 @@ struct acct_info /* security descriptor structures */ #include "rpc_secdes.h" +/* pac */ +#include "authdata.h" + /* different dce/rpc pipes */ #include "rpc_lsa.h" #include "rpc_netlogon.h" @@ -382,5 +385,4 @@ struct acct_info #include "rpc_spoolss.h" #include "rpc_dfs.h" #include "rpc_ds.h" - #endif /* _NT_DOMAIN_H */ diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c new file mode 100644 index 0000000000..3d25aec205 --- /dev/null +++ b/source3/libads/authdata.c @@ -0,0 +1,495 @@ +/* + Unix SMB/CIFS implementation. + kerberos authorization data (PAC) utility library + Copyright (C) Jim McDonough 2003 + + 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" + +#ifdef HAVE_KRB5 + +static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) +{ + DATA_BLOB pac_contents; + ASN1_DATA data; + int data_type; + + asn1_load(&data, *auth_data); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_Integer(&data, &data_type); + asn1_end_tag(&data); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_read_OctetString(&data, &pac_contents); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + return pac_contents; +} + +static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, + prs_struct *ps, int depth) +{ + if (NULL == sid_and_attr) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_sids"); + depth++; + + if (UNMARSHALLING(ps)) { + sid_and_attr->sid = + (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2)); + if (!sid_and_attr->sid) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth)) + return False; + + return True; +} + + +static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, + prs_struct *ps, int depth) +{ + if (NULL == sid_and_attr) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_attrs"); + depth++; + + if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr)) + return False; + if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs)) + return False; + + return True; +} + +static BOOL pac_io_krb_sid_and_attr_array(const char *desc, + KRB_SID_AND_ATTR_ARRAY *array, + uint32 num, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == array) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array"); + depth++; + + + if (!prs_uint32("count", ps, depth, &array->count)) + return False; + + if (UNMARSHALLING(ps)) { + array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *) + prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num); + if (!array->krb_sid_and_attrs) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + for (i=0; ikrb_sid_and_attrs[i], + ps, depth)) + return False; + + } + for (i=0; ikrb_sid_and_attrs[i], + ps, depth)) + return False; + + } + + return True; + +} + +static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, + prs_struct *ps, int depth) +{ + uint32 garbage; + if (NULL == info) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); + depth++; + + if (!prs_uint32("unknown", ps, depth, &garbage)) + return False; + if (!prs_uint32("unknown", ps, depth, &garbage)) + return False; + if (!prs_uint32("bufferlen", ps, depth, &garbage)) + return False; + if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) + return False; + if (!prs_uint32("pointer", ps, depth, &garbage)) + return False; + + if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) + return False; + if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) + return False; + if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth)) + return False; + if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time, + ps, depth)) + return False; + if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time, + ps, depth)) + return False; + if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time, + ps, depth)) + return False; + + if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, + ps, depth)) + return False; + if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path, + ps, depth)) + return False; + if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth)) + return False; + + if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) + return False; + if (!prs_uint16("reserved12", ps, depth, &info->reserved12)) + return False; + if (!prs_uint32("user_rid", ps, depth, &info->user_rid)) + return False; + if (!prs_uint32("group_rid", ps, depth, &info->group_rid)) + return False; + if (!prs_uint32("group_count", ps, depth, &info->group_count)) + return False; + /* I haven't seen this contain anything yet, but when it does + we will have to make sure we decode the contents in the middle + all the unistr2s ... */ + if (!prs_uint32("group_mem_ptr", ps, depth, + &info->group_membership_ptr)) + return False; + if (!prs_uint32("user_flags", ps, depth, &info->user_flags)) + return False; + + if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0])) + return False; + if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1])) + return False; + if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2])) + return False; + if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3])) + return False; + + if (!smb_io_unihdr("hdr_dom_controller", + &info->hdr_dom_controller, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) + return False; + + /* this should be followed, but just get ptr for now */ + if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid)) + return False; + + if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0])) + return False; + if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1])) + return False; + + /* might be acb_info */ + if (!prs_uint32("reserved17", ps, depth, &info->reserved17)) + return False; + + + if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0])) + return False; + if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1])) + return False; + if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2])) + return False; + if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3])) + return False; + if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4])) + return False; + if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5])) + return False; + if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6])) + return False; + + if (!prs_uint32("sid_count", ps, depth, &info->sid_count)) + return False; + if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids)) + return False; + if (!prs_uint32("ptr_res_group_dom_sid", ps, depth, + &info->ptr_res_group_dom_sid)) + return False; + if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) + return False; + if (!prs_uint32("ptr_res_group_sids", ps, depth, + &info->ptr_res_group_sids)) + return False; + + if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, + info->hdr_user_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_full_name", &info->uni_full_name, + info->hdr_full_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, + info->hdr_logon_script.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path, + info->hdr_profile_path.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir, + info->hdr_home_dir.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive, + info->hdr_dir_drive.buffer, ps, depth)) + return False; + + /* the group membership list will need to be handled here */ + + if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, + info->hdr_dom_controller.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, + info->hdr_dom_name.buffer, ps, depth)) + return False; + + if(info->ptr_dom_sid) + if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) + return False; + + + if (info->sid_count && info->ptr_extra_sids) { + if (!pac_io_krb_sid_and_attr_array("extra_sids", + &info->extra_sids, + info->sid_count, + ps, depth)) + return False; + } + + + return True; +} + + +static BOOL pac_io_pac_signature_data(const char *desc, + PAC_SIGNATURE_DATA *data, uint32 length, + prs_struct *ps, int depth) +{ + uint32 siglen = length - sizeof(uint32); + if (NULL == data) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); + depth++; + + if (!prs_uint32("type", ps, depth, &data->type)) + return False; + if (UNMARSHALLING(ps)) { + data->signature = prs_alloc_mem(ps, siglen); + if (!data->signature) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen)) + return False; + + return True; +} + +static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, + prs_struct *ps, int depth) +{ + if (NULL == hdr) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr"); + depth++; + + if (!prs_align(ps)) + return False; + + if (hdr->offset != prs_offset(ps)) { + DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n", + hdr->offset, prs_offset(ps))); + prs_set_offset(ps, hdr->offset); + } + + if (UNMARSHALLING(ps) && hdr->size > 0) { + hdr->ctr = (PAC_INFO_CTR *) + prs_alloc_mem(ps, sizeof(PAC_INFO_CTR)); + if (!hdr->ctr) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + switch(hdr->type) { + case PAC_TYPE_LOGON_INFO: + DEBUG(5, ("PAC_TYPE_LOGON_INFO\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *) + prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO)); + if (!hdr->ctr->pac.logon_info) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info, + ps, depth)) + return False; + break; + + case PAC_TYPE_SERVER_CHECKSUM: + DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *) + prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + if (!hdr->ctr->pac.srv_cksum) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum, + hdr->size, ps, depth)) + return False; + break; + + case PAC_TYPE_PRIVSVR_CHECKSUM: + DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *) + prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + if (!hdr->ctr->pac.privsrv_cksum) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_signature_data(desc, + hdr->ctr->pac.privsrv_cksum, + hdr->size, ps, depth)) + return False; + break; + + default: + /* dont' know, so we need to skip it */ + DEBUG(3, ("unknown PAC type %d\n", hdr->type)); + prs_set_offset(ps, prs_offset(ps) + hdr->size); + } + + return True; +} + +static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr, + prs_struct *ps, int depth) +{ + if (NULL == hdr) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_info_hdr"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("type", ps, depth, &hdr->type)) + return False; + if (!prs_uint32("size", ps, depth, &hdr->size)) + return False; + if (!prs_uint32("offset", ps, depth, &hdr->offset)) + return False; + if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi)) + return False; + + return True; +} + +static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == data) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_data"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers)) + return False; + if (!prs_uint32("version", ps, depth, &data->version)) + return False; + + if (UNMARSHALLING(ps) && data->num_buffers > 0) { + if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *) + prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) * + data->num_buffers)) == NULL) { + return False; + } + } + + for (i=0; inum_buffers; i++) { + if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps, + depth)) + return False; + } + + for (i=0; inum_buffers; i++) { + if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i], + ps, depth)) + return False; + } + + return True; +} + +PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) +{ + DATA_BLOB pac_data_blob = unwrap_pac(auth_data); + prs_struct ps; + PAC_DATA *pac_data; + + DEBUG(5,("dump_pac_data\n")); + prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL); + prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length); + prs_set_offset(&ps, 0); + + pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA)); + pac_io_pac_data("pac data", pac_data, &ps, 0); + + prs_mem_free(&ps); + + return pac_data; +} + +#endif diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 4d9a1bf765..56ec33b0a6 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -148,6 +148,12 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, get_auth_data_from_tkt(auth_data, tkt); + { + TALLOC_CTX *ctx = talloc_init("pac data"); + decode_pac_data(auth_data); + talloc_destroy(ctx); + } + #if 0 if (tkt->enc_part2) { file_save("/tmp/authdata.dat", -- cgit From 3b89c0656c800177cbb086041978ab65450e5d5a Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 7 Apr 2003 18:03:02 +0000 Subject: fix wrong string handling thanks to Stefan (metzte) Metzmacher (This used to be commit 99c2e11ccfe04867e84b467b0e82de8415c1dcee) --- source3/modules/vfs_recycle.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index a669d864c6..100db69cb6 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -552,9 +552,11 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) goto done; } - temp_name = (char *)strdup(recbin->repository); + temp_name = (char *)malloc(PATH_MAX); ALLOC_CHECK(temp_name, done); - + safe_strcpy(temp_name, recbin->repository, PATH_MAX - 1); + *temp_name = '\0'; + /* see if we need to recreate the original directory structure in the recycle bin */ if (recbin->keep_dir_tree == True) { safe_strcat(temp_name, "/", PATH_MAX - 1); @@ -573,7 +575,6 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) } } - final_name = NULL; asprintf(&final_name, "%s/%s", temp_name, base); ALLOC_CHECK(final_name, done); DEBUG(10, ("recycle.bin: recycled file name: %s\n", temp_name)); /* new filename with path */ -- cgit From eac27adfb3b7b2afe293a4e394cd84b870302d02 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 7 Apr 2003 18:05:35 +0000 Subject: remove unnened and wrong instructions (This used to be commit 671579874e51b28ffdfc094cdf34a0090567e0cc) --- source3/modules/vfs_recycle.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index 100db69cb6..18056fe796 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -521,7 +521,6 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) /* extract filename and path */ path_name = (char *)malloc(PATH_MAX); ALLOC_CHECK(path_name, done); - *path_name = '\0'; safe_strcpy(path_name, file_name, PATH_MAX - 1); base = strrchr(path_name, '/'); if (base == NULL) { @@ -555,7 +554,6 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) temp_name = (char *)malloc(PATH_MAX); ALLOC_CHECK(temp_name, done); safe_strcpy(temp_name, recbin->repository, PATH_MAX - 1); - *temp_name = '\0'; /* see if we need to recreate the original directory structure in the recycle bin */ if (recbin->keep_dir_tree == True) { -- cgit From d1c6c05ab045e1794e16f18ad7f9637272bffabd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Apr 2003 18:26:58 +0000 Subject: BUGS.txt -> Bugs Appendix in HOWTO collection (This used to be commit 1e1ef7a7b52f34ab784a7bac570235de221a64b6) --- source3/lib/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/lib/fault.c b/source3/lib/fault.c index e132ed8f67..a9e1b7bbb9 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -35,7 +35,7 @@ static void fault_report(int sig) DEBUG(0,("===============================================================\n")); DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),VERSION)); - DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n")); + DEBUG(0,("\nPlease read the appendix Bugs of the Samba HOWTO collection\n")); DEBUG(0,("===============================================================\n")); smb_panic("internal error"); -- cgit From 1d247da97a46693f3f4c8eceef03f685de5074df Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 7 Apr 2003 20:34:46 +0000 Subject: Some comment updates, notably that I haven't seen the group membership arrays yet (the ones that are rid-only). (This used to be commit 0a5b5d00db42de868c72ec3d9d1d747c9ef391e4) --- source3/include/authdata.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3') diff --git a/source3/include/authdata.h b/source3/include/authdata.h index dc9f217549..1521185a8f 100644 --- a/source3/include/authdata.h +++ b/source3/include/authdata.h @@ -33,6 +33,11 @@ typedef struct pac_signature_data { uint8 *signature; } PAC_SIGNATURE_DATA; +typedef struct group_membership { + uint32 rid; + uint32 attrs; +} GROUP_MEMBERSHIP; + typedef struct krb_sid_and_attrs { uint32 sid_ptr; uint32 attrs; @@ -99,7 +104,11 @@ typedef struct pac_logon_info { UNISTR2 uni_dom_controller; UNISTR2 uni_dom_name; DOM_SID2 dom_sid; + /* group membership array needs to go in here. + I've not seen it on the wire */ KRB_SID_AND_ATTR_ARRAY extra_sids; + DOM_SID2 res_group_dom_sid; + /* resource group membership array needs to go in here */ } PAC_LOGON_INFO; -- cgit From 38ec539cf5afeed3fe75f82e9aecbab7dc7f46ec Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 7 Apr 2003 23:45:22 +0000 Subject: We never actually got an 'ads' auth module, so don't send the auth subsystem off on a wild probing spree looking for it. Andrew Bartlett (This used to be commit 7c7c5594b3dfd460d09bccd409ccbf64c6b42338) --- source3/auth/auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/auth/auth.c b/source3/auth/auth.c index f9df255595..71e9ab0428 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -443,7 +443,7 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) break; case SEC_ADS: DEBUG(5,("Making default auth method list for security=ADS\n")); - auth_method_list = str_list_make("guest sam ads winbind ntdomain", NULL); + auth_method_list = str_list_make("guest sam winbind ntdomain", NULL); break; default: DEBUG(5,("Unknown auth method!\n")); -- cgit From 65289c353b77b31a746bcd36fb7fcbef01947187 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Tue, 8 Apr 2003 03:01:02 +0000 Subject: Merge from 3_0: Build a lookup table of valid DOS characters just once, when init_iconv is first called. Use this in check_dos_char rather than doing the conversion every time. Much faster. (This used to be commit e8f1399323745a93ba9df97553effcf2d7629850) --- source3/lib/charcnv.c | 16 +++++++++++----- source3/lib/util_unistr.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index f025e93718..d727628e41 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -59,7 +59,7 @@ static const char *charset_name(charset_t ch) return ret; } -static void lazy_initialize_conv(void) +void lazy_initialize_conv(void) { static int initialized = False; @@ -67,14 +67,16 @@ static void lazy_initialize_conv(void) initialized = True; load_case_tables(); init_iconv(); - init_valid_table(); } } /** - Initialize iconv conversion descriptors. -**/ - + * Initialize iconv conversion descriptors. + * + * This is called the first time it is needed, and also called again + * every time the configuration is reloaded, because the charset or + * codepage might have changed. + **/ void init_iconv(void) { int c1, c2; @@ -112,6 +114,10 @@ void init_iconv(void) } if (did_reload) { + /* XXX: Does this really get called every time the dos + * codepage changes? */ + /* XXX: Is the did_reload test too strict? */ + init_doschar_table(); init_valid_table(); } } diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index c666155f9f..812859000a 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -31,6 +31,14 @@ static smb_ucs2_t *upcase_table; static smb_ucs2_t *lowcase_table; static uint8 *valid_table; +/** + * This table says which Unicode characters are valid dos + * characters. + * + * Each value is just a single bit. + **/ +static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */ + /******************************************************************* load the case handling tables @@ -84,6 +92,21 @@ void load_case_tables(void) and mapped back to the same character in ucs2 */ static int check_dos_char(smb_ucs2_t c) +{ + static int initialized = False; + + if (!initialized) { + initialized = True; + init_doschar_table(); + } + + /* Find the right byte, and right bit within the byte; return + * 1 or 0 */ + return (doschar_table[(c & 0xffff) / 8] & (1 << (c & 7))) != 0; +} + + +static int check_dos_char_slowly(smb_ucs2_t c) { char buf[10]; smb_ucs2_t c2 = 0; @@ -95,6 +118,31 @@ static int check_dos_char(smb_ucs2_t c) return (c == c2); } + +/** + * Fill out doschar table the hard way, by examining each character + **/ +void init_doschar_table(void) +{ + int i, j, byteval; + + /* For each byte of packed table */ + + for (i = 0; i <= 0xffff; i += 8) { + byteval = 0; + for (j = 0; j <= 7; j++) { + smb_ucs2_t c; + + c = i + j; + + if (check_dos_char_slowly(c)) + byteval |= 1 << j; + } + doschar_table[i/8] = byteval; + } +} + + /** * Load the valid character map table from valid.dat or * create from the configured codepage. -- cgit From 09e9e5a2fd510e01262a733384b23d0e1a1bf541 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 8 Apr 2003 04:07:22 +0000 Subject: Added some preprocessor tricks to stop TRUE and FALSE from continually creeping back in to the source. Use True and False instead. (This used to be commit 5a5a7ce7479a56ca2d472658511a47c9147c0d5b) --- source3/include/includes.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/include/includes.h b/source3/include/includes.h index bf71ed54cf..61aee975c0 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -1274,5 +1274,18 @@ void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes); BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]); #endif /* HAVE_KRB5 */ -#endif /* _INCLUDES_H */ +/* TRUE and FALSE are part of the C99 standard and gcc, but + unfortunately many vendor compilers don't support them. Use True + and False instead. */ + +#ifdef TRUE +#undef TRUE +#endif +#define TRUE __ERROR__XX__DONT_USE_TRUE +#ifdef FALSE +#undef FALSE +#endif +#define FALSE __ERROR__XX__DONT_USE_FALSE + +#endif /* _INCLUDES_H */ -- cgit From b610c18bd9eba4d67d37f054775168f6d4c13f5c Mon Sep 17 00:00:00 2001 From: John Terpstra Date: Tue, 8 Apr 2003 04:44:26 +0000 Subject: Patch from Steve Langasek fix up two issues in pam_smbpass. The first, more important issue is adding support for the (apparently new) LOCAL_SET_PASSWORD flag to local_password_change(), without which pam_smbpass is a complete and utter no-op. The second, lesser issue is that with the advent of ldapsam, it's possible for pam_smbpass to generate a SIGPIPE that isn't handled by the calling application. The most basic signal wrapping is put in place to prevent this. Beyond that, the only thing in the patch is a bit of reformatting to make pam_smb_passwd.c look a bit more like the rest of the code in CVS. (This used to be commit 7cb5af35273097f913bff6894fe03050a18e1def) --- source3/pam_smbpass/pam_smb_acct.c | 12 +++- source3/pam_smbpass/pam_smb_auth.c | 7 ++ source3/pam_smbpass/pam_smb_passwd.c | 124 +++++++++++++++++++---------------- 3 files changed, 85 insertions(+), 58 deletions(-) (limited to 'source3') diff --git a/source3/pam_smbpass/pam_smb_acct.c b/source3/pam_smbpass/pam_smb_acct.c index 0803ef82a2..2ea7eea7d8 100644 --- a/source3/pam_smbpass/pam_smb_acct.c +++ b/source3/pam_smbpass/pam_smb_acct.c @@ -47,7 +47,7 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, const char *name; SAM_ACCOUNT *sampass = NULL; - + void (*oldsig_handler)(int); extern BOOL in_client; /* Samba initialization. */ @@ -69,8 +69,12 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, _log_err( LOG_DEBUG, "acct: username [%s] obtained", name ); } + /* Getting into places that might use LDAP -- protect the app + from a SIGPIPE it's not expecting */ + oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); if (!initialize_password_db(True)) { _log_err( LOG_ALERT, "Cannot access samba password database" ); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_AUTHINFO_UNAVAIL; } @@ -78,8 +82,10 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, pdb_init_sam(&sampass); pdb_getsampwnam(sampass, name ); - if (!sampass) + if (!sampass) { + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; + } if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { if (on( SMB_DEBUG, ctrl )) { @@ -90,11 +96,13 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, , "Your account has been disabled; " "please see your system administrator." ); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_ACCT_EXPIRED; } /* TODO: support for expired passwords. */ + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_SUCCESS; } diff --git a/source3/pam_smbpass/pam_smb_auth.c b/source3/pam_smbpass/pam_smb_auth.c index e5cc12e2f6..f4cbb59af3 100644 --- a/source3/pam_smbpass/pam_smb_auth.c +++ b/source3/pam_smbpass/pam_smb_auth.c @@ -36,6 +36,8 @@ #define AUTH_RETURN \ do { \ + /* Restore application signal handler */ \ + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); \ if(ret_data) { \ *ret_data = retval; \ pam_set_data( pamh, "smb_setcred_return" \ @@ -65,6 +67,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, SAM_ACCOUNT *sampass = NULL; extern BOOL in_client; const char *name; + void (*oldsig_handler)(int); BOOL found; /* Points to memory managed by the PAM library. Do not free. */ @@ -93,6 +96,10 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, _log_err( LOG_DEBUG, "username [%s] obtained", name ); } + /* Getting into places that might use LDAP -- protect the app + from a SIGPIPE it's not expecting */ + oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); + if (!initialize_password_db(True)) { _log_err( LOG_ALERT, "Cannot access samba password database" ); retval = PAM_AUTHINFO_UNAVAIL; diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c index 91eae3c7a1..9e75efccf4 100644 --- a/source3/pam_smbpass/pam_smb_passwd.c +++ b/source3/pam_smbpass/pam_smb_passwd.c @@ -1,18 +1,22 @@ -/* Unix NT password database implementation, version 0.7.5. - * - * 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. +/* + Unix SMB/CIFS implementation. + Use PAM to update user passwords in the local SAM + Copyright (C) Steve Langasek 1998-2003 + + 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. + */ /* indicate the following groups are defined */ @@ -20,12 +24,13 @@ #include "includes.h" -#ifndef LINUX +/* This is only used in the Sun implementation. FIXME: we really + want a define here that distinguishes between the Solaris PAM + and others (including FreeBSD). */ -/* This is only used in the Sun implementation. */ +#ifndef LINUX #include - -#endif /* LINUX */ +#endif #include @@ -35,34 +40,34 @@ int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, const char *pass_new ) { - int retval; - pstring err_str; - pstring msg_str; - - err_str[0] = '\0'; - msg_str[0] = '\0'; - - retval = local_password_change( user, 0, pass_new, err_str, sizeof(err_str), - msg_str, sizeof(msg_str) ); - - if (!retval) { - if (*err_str) { - err_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str ); - } - - /* FIXME: what value is appropriate here? */ - retval = PAM_AUTHTOK_ERR; - } else { - if (*msg_str) { - msg_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str ); - } - retval = PAM_SUCCESS; - } - - return retval; + int retval; + pstring err_str; + pstring msg_str; + + err_str[0] = '\0'; + msg_str[0] = '\0'; + + retval = local_password_change( user, LOCAL_SET_PASSWORD, pass_new, + err_str, sizeof(err_str), + msg_str, sizeof(msg_str) ); + + if (!retval) { + if (*err_str) { + err_str[PSTRING_LEN-1] = '\0'; + make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str ); + } + + /* FIXME: what value is appropriate here? */ + retval = PAM_AUTHTOK_ERR; + } else { + if (*msg_str) { + msg_str[PSTRING_LEN-1] = '\0'; + make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str ); + } + retval = PAM_SUCCESS; + } + return retval; } @@ -92,6 +97,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, extern BOOL in_client; SAM_ACCOUNT *sampass = NULL; + void (*oldsig_handler)(int); const char *user; char *pass_old; char *pass_new; @@ -120,18 +126,25 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, _log_err( LOG_DEBUG, "username [%s] obtained", user ); } + /* Getting into places that might use LDAP -- protect the app + from a SIGPIPE it's not expecting */ + oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); + if (!initialize_password_db(True)) { _log_err( LOG_ALERT, "Cannot access samba password database" ); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_AUTHINFO_UNAVAIL; } /* obtain user record */ if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) { - return nt_status_to_pam(nt_status); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); + return nt_status_to_pam(nt_status); } if (!pdb_getsampwnam(sampass,user)) { _log_err( LOG_ALERT, "Failed to find entry for user %s.", user ); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; } @@ -146,6 +159,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, if (_smb_blankpasswd( ctrl, sampass )) { pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_SUCCESS; } @@ -159,6 +173,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, if (Announce == NULL) { _log_err(LOG_CRIT, "password: out of memory"); pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_BUF_ERR; } strncpy( Announce, greeting, sizeof(greeting) ); @@ -174,6 +189,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, _log_err( LOG_NOTICE , "password - (old) token not obtained" ); pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; } @@ -188,19 +204,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, pass_old = NULL; pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; } else if (flags & PAM_UPDATE_AUTHTOK) { -#if 0 - /* We used to return when this flag was set, but that breaks - password synchronization when /other/ tokens are expired. For - now, we change the password whenever we're asked. SRL */ - if (flags & PAM_CHANGE_EXPIRED_AUTHTOK) { - pdb_free_sam(&sampass); - return PAM_SUCCESS; - } -#endif /* * obtain the proposed password */ @@ -226,6 +234,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, if (retval != PAM_SUCCESS) { _log_err( LOG_NOTICE, "password: user not authenticated" ); pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; } @@ -253,6 +262,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, } pass_old = NULL; /* tidy up */ pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; } @@ -272,6 +282,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, _log_err(LOG_NOTICE, "new password not acceptable"); pass_new = pass_old = NULL; /* tidy up */ pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; } @@ -312,6 +323,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, } pdb_free_sam(&sampass); + CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; } -- cgit From d3d0951a28387cbb20e842a1e725ead4a76a0d21 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Tue, 8 Apr 2003 05:01:18 +0000 Subject: Merge from 1.2.2.2: Update for new ComfyChair interface. (This used to be commit 9de9899165fbf403e369d8ebadd171ffdde8c3b7) --- source3/stf/strings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/stf/strings.py b/source3/stf/strings.py index a67e137058..8fc12d4e39 100755 --- a/source3/stf/strings.py +++ b/source3/stf/strings.py @@ -33,7 +33,7 @@ def signum(a): class StrCaseCmp_Ascii_Tests(comfychair.TestCase): """String comparisons in simple ASCII""" def run_strcmp(self, a, b, expect): - out = self.runcmd('t_strcmp \"%s\" \"%s\"' % (a, b)) + out, err = self.runcmd('t_strcmp \"%s\" \"%s\"' % (a, b)) if signum(int(out)) != expect: self.fail("comparison failed:\n" " a=%s\n" -- cgit From bce94d35f125eaeaa4db7866503418b8f281edf2 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Tue, 8 Apr 2003 08:05:01 +0000 Subject: Integrate abartlet's t_push_ucs2 test into test framework: - Build t_push_ucs2 as part of check-programs, the prerequisite for "make check". - t_push_ucs2.c: Load configuration from /dev/null so that we get a unix_charset of UTF-8 and can do meaningful UCS2 tests. Better comment. - Add a test to strings.py which tries conversion UTF8->UCS2->UTF8 and checks the results. Do this for English, Latin-1, and Katakana strings. - Add Python module with symbolic names for a handful of UNICODE characters. (This used to be commit 275e095c92ac74815ab9e388a0e83cdb7ddd85f3) --- source3/Makefile.in | 2 +- source3/stf/strings.py | 40 ++++++++++++++++++++++++++++++++++++++-- source3/stf/unicodenames.py | 33 +++++++++++++++++++++++++++++++++ source3/torture/t_push_ucs2.c | 8 ++++++-- 4 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 source3/stf/unicodenames.py (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index fc18fc2ff2..b9504f5b15 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1347,4 +1347,4 @@ check: check-programs python stf/standardcheck.py # These are called by the test suite -check-programs: bin/t_strcmp +check-programs: bin/t_strcmp bin/t_push_ucs2 diff --git a/source3/stf/strings.py b/source3/stf/strings.py index 8fc12d4e39..4e070c0444 100755 --- a/source3/stf/strings.py +++ b/source3/stf/strings.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#! /usr/bin/python # Comfychair test cases for Samba string functions. @@ -19,7 +19,22 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA +# XXX: All this code assumes that the Unix character set is UTF-8, +# which is the most common setting. I guess it would be better to +# force it to that value while running the tests. I'm not sure of the +# best way to do that yet. +# +# Note that this is NOT the case in C code until the loadparm table is +# intialized -- the default seems to be ASCII, which rather lets Samba +# off the hook. :-) The best way seems to be to put this in the test +# harnesses: +# +# lp_load("/dev/null", True, False, False); +# +# -- mbp + import sys, re, comfychair +from unicodenames import * def signum(a): if a < 0: @@ -28,6 +43,23 @@ def signum(a): return +1 else: return 0 + + +class PushUCS2_Tests(comfychair.TestCase): + """Conversion to/from UCS2""" + def runtest(self): + OE = LATIN_CAPITAL_LETTER_O_WITH_DIARESIS + oe = LATIN_CAPITAL_LETTER_O_WITH_DIARESIS + cases = ['hello', + 'hello world', + 'g' + OE + OE + 'gomobile', + 'g' + OE + oe + 'gomobile', + u'foo\u0100', + KATAKANA_LETTER_A * 20, + ] + for u8str in cases: + out, err = self.runcmd("t_push_ucs2 \"%s\"" % u8str.encode('utf-8')) + self.assert_equal(out, "0\n") class StrCaseCmp_Ascii_Tests(comfychair.TestCase): @@ -61,9 +93,13 @@ class StrCaseCmp_Ascii_Tests(comfychair.TestCase): self.run_strcmp(a, b, expect) # Define the tests exported by this module -tests = [StrCaseCmp_Ascii_Tests] +tests = [StrCaseCmp_Ascii_Tests, + PushUCS2_Tests] # Handle execution of this file as a main program if __name__ == '__main__': comfychair.main(tests) +# Local variables: +# coding: utf-8 +# End: diff --git a/source3/stf/unicodenames.py b/source3/stf/unicodenames.py new file mode 100644 index 0000000000..d4100cb7f9 --- /dev/null +++ b/source3/stf/unicodenames.py @@ -0,0 +1,33 @@ +#! /usr/bin/python + +# Copyright (C) 2003 by Martin Pool +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + + +""" +Defines symbolic names for a few UNICODE characters, to make test +source code more readable on machines that don't have all the +necessary fonts. + +You can do "import *" on this file safely. +""" + +LATIN_CAPITAL_LETTER_N_WITH_TILDE = u'\u004e' +LATIN_CAPITAL_LETTER_O_WITH_DIARESIS = u'\u00d6' +LATIN_SMALL_LETTER_O_WITH_DIARESIS = u'\u00f6' + +KATAKANA_LETTER_A = u'\u30a2' diff --git a/source3/torture/t_push_ucs2.c b/source3/torture/t_push_ucs2.c index ca04394acc..86ae1b9b6c 100644 --- a/source3/torture/t_push_ucs2.c +++ b/source3/torture/t_push_ucs2.c @@ -30,10 +30,14 @@ static int check_push_ucs2(const char *orig) int main(int argc, char *argv[]) { int i, ret = 0; - + + /* Needed to initialize character set */ + lp_load("/dev/null", True, False, False); + if (argc != 2) { fprintf(stderr, "usage: %s STRING1\n" - "Converts a string, prints the results of strcmp\n", + "Checks that a string translated UNIX->UCS2->UNIX is unchanged\n" + "Should be always 0\n", argv[0]); return 2; } -- cgit From 1eda5b4987360b0f2f2e330e8227962fdb890623 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 8 Apr 2003 10:46:46 +0000 Subject: some more debugging in case of failure (This used to be commit 9374f8692f6587b5f773c72b7847b64edeee9614) --- source3/sam/idmap.c | 2 ++ source3/sam/idmap_tdb.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/sam/idmap.c b/source3/sam/idmap.c index 00b45565bb..06fcc5a956 100644 --- a/source3/sam/idmap.c +++ b/source3/sam/idmap.c @@ -91,6 +91,7 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) ret = local_map->set_mapping(sid, id, id_type); if (NT_STATUS_IS_ERR(ret)) { DEBUG (0, ("idmap_set_mapping: Error, unable to modify local cache!\n")); + DEBUGADD(0, ("Error num. %d", NT_STATUS_V(ret))); return ret; } @@ -100,6 +101,7 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) remote_map->set_mapping(sid, id, id_type); if (NT_STATUS_IS_ERR(ret)) { DEBUG (0, ("idmap_set_mapping: Error, unable to modify remote cache!\n")); + DEBUGADD(0, ("Error num. %d", NT_STATUS_V(ret))); } } diff --git a/source3/sam/idmap_tdb.c b/source3/sam/idmap_tdb.c index 8ecf4d6e7e..7080ac56e6 100644 --- a/source3/sam/idmap_tdb.c +++ b/source3/sam/idmap_tdb.c @@ -224,7 +224,6 @@ static NTSTATUS db_set_mapping(DOM_SID *sid, unid_t id, int id_type) ksid.dptr = ksidstr; ksid.dsize = strlen(ksidstr) + 1; - id_type &= ID_TYPEMASK; if (id_type & ID_USERID) { slprintf(kidstr, sizeof(kidstr), "UID %d", id.uid); } else if (id_type & ID_GROUPID) { @@ -237,11 +236,11 @@ static NTSTATUS db_set_mapping(DOM_SID *sid, unid_t id, int id_type) kid.dsize = strlen(kidstr) + 1; if (tdb_store(idmap_tdb, ksid, kid, TDB_INSERT) == -1) { - /* TODO: print tdb error !! */ + DEBUG(0, ("idb_set_mapping: tdb_store 1 error: %s", tdb_errorstr(idmap_tdb))); return NT_STATUS_UNSUCCESSFUL; } if (tdb_store(idmap_tdb, kid, ksid, TDB_INSERT) == -1) { - /* TODO: print tdb error !! */ + DEBUG(0, ("idb_set_mapping: tdb_store 2 error: %s", tdb_errorstr(idmap_tdb))); return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK; -- cgit From a87d3b2cba01f0d0417de0b7a1070872741b2762 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 8 Apr 2003 15:38:09 +0000 Subject: Update smbmount to include unicode and lfs capabilities options -- smbfs supports this already (This used to be commit a003a5f052a9ef7ad14f6f79157669d1bbd37f96) --- source3/client/smbmount.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/client/smbmount.c b/source3/client/smbmount.c index 98302485e4..1ee7dbc8cb 100644 --- a/source3/client/smbmount.c +++ b/source3/client/smbmount.c @@ -51,6 +51,8 @@ static unsigned mount_dmask; static BOOL use_kerberos; /* TODO: Add code to detect smbfs version in kernel */ static BOOL status32_smbfs = False; +static BOOL smbfs_has_unicode = False; +static BOOL smbfs_has_lfs = False; static void usage(void); @@ -201,15 +203,14 @@ static struct cli_state *do_connection(char *the_service) /* This should be right for current smbfs. Future versions will support large files as well as unicode and oplocks. */ - if (status32_smbfs) { - c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | - CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS); - } - else { - c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | - CAP_NT_FIND | CAP_STATUS32 | - CAP_LEVEL_II_OPLOCKS); - c->force_dos_errors = True; + c->capabilities &= ~(CAP_NT_SMBS | CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS); + if (!smbfs_has_lfs) + c->capabilities &= ~CAP_LARGE_FILES; + if (!smbfs_has_unicode) + c->capabilities &= ~CAP_UNICODE; + if (!status32_smbfs) { + c->capabilities &= ~CAP_STATUS32; + c->force_dos_errors = True; } if (!cli_session_setup(c, username, @@ -683,6 +684,8 @@ static void usage(void) scope= NetBIOS scope\n\ iocharset= Linux charset (iso8859-1, utf8)\n\ codepage= server codepage (cp850)\n\ + unicode use unicode when communicating with server\n\ + lfs large file system support\n\ ttl= dircache time to live\n\ guest don't prompt for a password\n\ ro mount read-only\n\ @@ -828,6 +831,10 @@ static void parse_mount_smb(int argc, char **argv) mount_ro = 0; } else if(!strcmp(opts, "ro")) { mount_ro = 1; + } else if(!strcmp(opts, "unicode")) { + smbfs_has_unicode = True; + } else if(!strcmp(opts, "lfs")) { + smbfs_has_lfs = True; } else { strncpy(p, opts, sizeof(pstring) - (p - options) - 1); p += strlen(opts); -- cgit From 90290b166b70dc2606d076f3266b6a9353a49c61 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 8 Apr 2003 17:34:16 +0000 Subject: reworked to not malloc PATH_MAX long strings corrected path_name creation (This used to be commit f4be4e70a12edae83b9b89622ca5077a7d3d5602) --- source3/modules/vfs_recycle.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index 18056fe796..d554f4bfdd 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -519,15 +519,16 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) */ /* extract filename and path */ - path_name = (char *)malloc(PATH_MAX); - ALLOC_CHECK(path_name, done); - safe_strcpy(path_name, file_name, PATH_MAX - 1); - base = strrchr(path_name, '/'); + base = strrchr(file_name, '/'); if (base == NULL) { base = file_name; - safe_strcpy(path_name, "/", PATH_MAX - 1); + path_name = strdup("/"); + ALLOC_CHECK(path_name, done); } else { + path_name = strdup(file_name); + ALLOC_CHECK(path_name, done); + path_name[base - file_name] = '\0'; base++; } @@ -551,14 +552,13 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) goto done; } - temp_name = (char *)malloc(PATH_MAX); - ALLOC_CHECK(temp_name, done); - safe_strcpy(temp_name, recbin->repository, PATH_MAX - 1); - /* see if we need to recreate the original directory structure in the recycle bin */ if (recbin->keep_dir_tree == True) { - safe_strcat(temp_name, "/", PATH_MAX - 1); - safe_strcat(temp_name, path_name, PATH_MAX - 1); + asprintf(&temp_name, "%s/%s", recbin->repository, path_name); + ALLOC_CHECK(temp_name, done); + } else { + temp_name = strdup(recbin->repository); + ALLOC_CHECK(temp_name, done); } exist = recycle_directory_exist(conn, temp_name); -- cgit From 667e6d8279844e8a27b315fa900d1bbfbe874926 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Apr 2003 00:00:50 +0000 Subject: Ensure print queue array is zeroed out before returning. Jeremy. (This used to be commit 337cac7810369430045d7a136176bd57e55adcde) --- source3/printing/print_generic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c index 4d77b827bf..0b062ebdd9 100644 --- a/source3/printing/print_generic.c +++ b/source3/printing/print_generic.c @@ -214,6 +214,7 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1)); if (queue) { + memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1)); for (i=0; i Date: Wed, 9 Apr 2003 03:51:52 +0000 Subject: Winbind client for AIX. Written by Steve Roylance. (This used to be commit e37d025e6724196925c43c8ce558064ed5c072c5) --- source3/nsswitch/winbind_nss_aix.c | 411 +++++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) (limited to 'source3') diff --git a/source3/nsswitch/winbind_nss_aix.c b/source3/nsswitch/winbind_nss_aix.c index e69de29bb2..ba5332bf98 100644 --- a/source3/nsswitch/winbind_nss_aix.c +++ b/source3/nsswitch/winbind_nss_aix.c @@ -0,0 +1,411 @@ +/* + Unix SMB/CIFS implementation. + + AIX loadable authentication mmodule, providing identification + routines against Samba winbind/Windows NT Domain + + Copyright (C) Tim Potter 2003 + Copyright (C) Steve Roylance 2003 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include + +#include "winbind_client.h" + +#define MAX_GETPWENT_USERS 250 +#define MAX_GETGRENT_USERS 250 +/* #define WB_AIX_DEBUG */ + +static struct passwd *fill_pwent(struct winbindd_pw *pw) +{ + struct passwd *result; + + if (!(result = malloc(sizeof(struct passwd)))) + goto out; + + ZERO_STRUCTP(result); + + /* User name */ + + if ((result->pw_name = malloc(strlen(pw->pw_name) + 1)) == NULL) + goto out; + + strcpy(result->pw_name, pw->pw_name); + + /* Password */ + + if ((result->pw_passwd = malloc(strlen(pw->pw_passwd) + 1)) == NULL) + goto out; + + strcpy(result->pw_passwd, pw->pw_passwd); + + /* [ug]id */ + + result->pw_uid = pw->pw_uid; + result->pw_gid = pw->pw_gid; + + /* GECOS */ + + if ((result->pw_gecos = malloc(strlen(pw->pw_gecos) + 1)) == NULL) + goto out; + + strcpy(result->pw_gecos, pw->pw_gecos); + + /* Home directory */ + + if ((result->pw_dir = malloc(strlen(pw->pw_dir) + 1)) == NULL) + goto out; + + strcpy(result->pw_dir, pw->pw_dir); + + /* Logon shell */ + + if ((result->pw_shell = malloc(strlen(pw->pw_shell) + 1)) == NULL) + goto out; + + strcpy(result->pw_shell, pw->pw_shell); +#ifdef WB_AIX_DEBUG + printf("wb_aix - returning filled pwent %s, %d\n", result->pw_name, result->pw_uid); +#endif + return result; + + /* A memory allocation failed, undo succesfull allocations and + return NULL */ + +out: + SAFE_FREE(result->pw_dir); + SAFE_FREE(result->pw_gecos); + SAFE_FREE(result->pw_passwd); + SAFE_FREE(result->pw_name); + SAFE_FREE(result); + + return NULL; +} + +static BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize) +{ + char *s; + BOOL quoted; + size_t len=1; + + if (!ptr) return(False); + + s = *ptr; + + /* default to simple separators */ + if (!sep) sep = " \t\n\r"; + + /* find the first non sep char */ + while (*s && strchr(sep,*s)) s++; + + /* nothing left? */ + if (! *s) return(False); + + /* copy over the token */ + for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) { + if (*s == '\"') { + quoted = !quoted; + } else { + len++; + *buff++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *buff = 0; + + return(True); +} + +static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem) +{ + fstring name; + int i; + char *tst; + struct group *result; + + if (!(result = malloc(sizeof(struct group)))) + goto out; + + ZERO_STRUCTP(result); + + /* Group name */ + + if ((result->gr_name = malloc(strlen(gr->gr_name) + 1)) == NULL) + goto out; + + strcpy(result->gr_name, gr->gr_name); + + /* Password */ + + if ((result->gr_passwd = malloc(strlen(gr->gr_passwd) + 1)) == NULL) + goto out; + + strcpy(result->gr_passwd, gr->gr_passwd); + + /* gid */ + + result->gr_gid = gr->gr_gid; + + /* Group membership */ + + if ((gr->num_gr_mem < 0) || !gr_mem) { + gr->num_gr_mem = 0; + } + + if (gr->num_gr_mem == 0) { + + /* Group is empty */ + + *(result->gr_mem) = NULL; + return result; + } + + if ((tst = malloc(((gr->num_gr_mem + 1) * sizeof(char *)))) == NULL) + goto out; + + result->gr_mem = (char **)tst; + + /* Start looking at extra data */ + + i = 0; + + while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) { + + /* Allocate space for member */ + + if (((result->gr_mem)[i] = + malloc(strlen(name) + 1)) == NULL) { + for ( i -= 1; i >= 0; i--) + SAFE_FREE((result->gr_mem)[i]); + goto out; + + } + + strcpy((result->gr_mem)[i], name); + i++; + } + + /* Terminate list */ + + (result->gr_mem)[i] = NULL; + +#ifdef WB_AIX_DEBUG + printf("wb_aix - returning filled grent %s, %d\n", result->gr_name, result->gr_gid); +#endif + return result; + + /* A memory allocation failed, undo succesfull allocations and + return NULL */ + +out: + SAFE_FREE(tst); + SAFE_FREE(result->gr_passwd); + SAFE_FREE(result->gr_name); + SAFE_FREE(result); + + return NULL; +} + + + +static struct group * +wb_aix_getgrgid (gid_t gid) +{ +/* take a group id and return a filled struct group */ + + struct winbindd_response response; + struct winbindd_request request; + + ZERO_STRUCT(response); + ZERO_STRUCT(request); +#ifdef WB_AIX_DEBUG + printf("wb_aix - getgrid for %d\n", gid); +#endif + + request.data.gid = gid; + + if (winbindd_request(WINBINDD_GETGRGID, &request, &response) + == NSS_STATUS_SUCCESS) { +#ifdef WB_AIX_DEBUG + printf("wb_aix - returned from winbind_request\n"); +#endif + return fill_grent(&response.data.gr, response.extra_data); + } + + return NULL; +} + +static struct group * +wb_aix_getgrnam (const char *name) +{ +/* take a group name and return a filled struct group */ + + struct winbindd_response response; + struct winbindd_request request; + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + +#ifdef WB_AIX_DEBUG + printf("wb_aix - getgrnam for %s\n", name); +#endif + + strncpy(request.data.groupname, name, + sizeof(request.data.groupname)); + request.data.groupname + [sizeof(request.data.groupname) - 1] = '\0'; + + + if (winbindd_request(WINBINDD_GETGRNAM, &request, &response) + == NSS_STATUS_SUCCESS) { +#ifdef WB_AIX_DEBUG + printf("wb_aix - returned from winbind_request\n"); +#endif + return fill_grent(&response.data.gr, response.extra_data); + } + return NULL; +} + +static char * +wb_aix_getgrset (const char *user) +{ +/* take a username and return a string containing a comma-separated list of + group id numbers to which the user belongs */ + + struct winbindd_response response; + struct winbindd_request request; + + char *tmpbuf, *result; + int i, idx = 0; + +#ifdef WB_AIX_DEBUG + printf("wb_aix - getgrset for %s\n", user); +#endif + strncpy(request.data.username, user, + sizeof(request.data.username) - 1); + request.data.username + [sizeof(request.data.username) - 1] = '\0'; + + + if (winbindd_request(WINBINDD_GETGROUPS, &request, &response) + == NSS_STATUS_SUCCESS) { + int num_gids = response.data.num_entries; + gid_t *gid_list = (gid_t *)response.extra_data; +#ifdef WB_AIX_DEBUG + printf("wb_aix - returned from winbind_request\n"); +#endif + + /* allocate a space large enough to contruct the string */ + if (!(tmpbuf = malloc(num_gids*12))) { + return NULL; + } + idx += sprintf(tmpbuf, "%d", gid_list[0]); + for (i = 1; i < num_gids; i++) { + tmpbuf[idx++] = ','; + idx += sprintf(tmpbuf+idx, "%d", gid_list[i]); + } + tmpbuf[idx] = '\0'; + if (!(result = malloc(idx+1))) { + /* allocate a string the right size to return, but + if that fails may as well return our working buffer + because it contains the same thing */ + return tmpbuf; + } + strcpy(result, tmpbuf); + SAFE_FREE(tmpbuf); + return result; + } + return NULL; +} + +static struct passwd * +wb_aix_getpwuid (uid_t uid) +{ +/* take a uid and return a filled struct passwd */ + + struct winbindd_response response; + struct winbindd_request request; + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + +#ifdef WB_AIX_DEBUG + printf("wb_aix - getpwid for %d\n", uid); +#endif + + request.data.uid = uid; + + if (winbindd_request(WINBINDD_GETPWUID, &request, &response) + == NSS_STATUS_SUCCESS) { +#ifdef WB_AIX_DEBUG + printf("wb_aix - returned from winbind_request\n"); +#endif + return fill_pwent(&response.data.pw); + } + return NULL; +} + +static struct passwd * +wb_aix_getpwnam (const char *name) +{ +/* take a username and return a filled struct passwd */ + + struct winbindd_response response; + struct winbindd_request request; + + ZERO_STRUCT(response); + ZERO_STRUCT(request); +#ifdef WB_AIX_DEBUG + printf("wb_aix - getpwnam for %s\n", name); +#endif + strncpy(request.data.username, name, + sizeof(request.data.username) - 1); + request.data.username + [sizeof(request.data.username) - 1] = '\0'; + + + if (winbindd_request(WINBINDD_GETPWNAM, &request, &response) + == NSS_STATUS_SUCCESS) { +#ifdef WB_AIX_DEBUG + printf("wb_aix - returned from winbind_request\n"); +#endif + return fill_pwent(&response.data.pw); + } + return NULL; +} + +int +wb_aix_init (struct secmethod_table *methods) +{ + memset(methods, 0, sizeof(*methods)); + + /* identification methods, this is the minimum requried for a + working module */ + + methods->method_getgrgid = wb_aix_getgrgid; + methods->method_getgrnam = wb_aix_getgrnam; + methods->method_getgrset = wb_aix_getgrset; + methods->method_getpwnam = wb_aix_getpwnam; + methods->method_getpwuid = wb_aix_getpwuid; + + return AUTH_SUCCESS; +} -- cgit From e725e6a0b793ca7efdaef0acdcb23b264b9c5c34 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 9 Apr 2003 04:05:42 +0000 Subject: Autoconfiscate the name of the winbind shared library file. Under IRIX this is libns_winbind - everyone else is libnss_winbind. This simplifies the Makefile a bit and also fixes the 'nsswitch' target under IRIX. (This used to be commit 69c392bc127bf69876f4dedae8c3a6976219d448) --- source3/Makefile.in | 13 ++++--------- source3/configure.in | 4 ++++ 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index b9504f5b15..8301ca7eef 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -645,7 +645,7 @@ smbfilter : SHOWFLAGS bin/smbfilter@EXEEXT@ talloctort : SHOWFLAGS bin/talloctort@EXEEXT@ -nsswitch : SHOWFLAGS bin/winbindd@EXEEXT@ bin/wbinfo@EXEEXT@ nsswitch/libnss_winbind.@SHLIBEXT@ nsswitch/pam_winbind.@SHLIBEXT@ +nsswitch : SHOWFLAGS bin/winbindd@EXEEXT@ bin/wbinfo@EXEEXT@ nsswitch/@WINBIND_NSS@.@SHLIBEXT@ nsswitch/pam_winbind.@SHLIBEXT@ wins : SHOWFLAGS nsswitch/libnss_wins.@SHLIBEXT@ @@ -952,15 +952,10 @@ bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS) \ @LDAP_LIBS@ -nsswitch/libns_winbind.@SHLIBEXT@: $(WINBIND_NSS_PICOBJS) +nsswitch/@WINBIND_NSS@.@SHLIBEXT@: $(WINBIND_NSS_PICOBJS) @echo "Linking $@" - @$(SHLD) @LDSHFLAGS@ -o $@ $(WINBIND_NSS_PICOBJS) @WINBIND_NSS_EXTRA_LIBS@ \ - @SONAMEFLAG@`basename $@` - -nsswitch/libnss_winbind.@SHLIBEXT@: $(WINBIND_NSS_PICOBJS) - @echo "Linking $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_NSS_PICOBJS) @WINBIND_NSS_EXTRA_LIBS@ \ - @SONAMEFLAG@`basename $@` + @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_NSS_PICOBJS) \ + @WINBIND_NSS_EXTRA_LIBS@ @SONAMEFLAG@`basename $@` nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_OBJ) bin/.dummy @echo Linking $@ diff --git a/source3/configure.in b/source3/configure.in index b9e32d6208..2b086d3d3b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -3222,12 +3222,15 @@ AC_MSG_CHECKING(whether to build winbind) HAVE_WINBIND=yes +WINBIND_NSS=libnss_winbind + case "$host_os" in *linux*) WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o" ;; *irix*) WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o" + WINBIND_NSS="libns_winbind" ;; *solaris*) # Solaris winbind client is implemented as a wrapper around @@ -3248,6 +3251,7 @@ case "$host_os" in ;; esac +AC_SUBST(WINBIND_NSS) AC_SUBST(WINBIND_NSS_EXTRA_OBJS) AC_SUBST(WINBIND_NSS_EXTRA_LIBS) -- cgit From 0aad60636d2ac86f6700ad137899fa2236e46509 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 9 Apr 2003 04:20:29 +0000 Subject: Install libsmbclient.h from $(srcdir) (This used to be commit d396f57678056af6b0c384df324f94992cca85d0) --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 8301ca7eef..dc0a5ccfa5 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1131,7 +1131,7 @@ installclientlib: libsmbclient -$(INSTALLCLIENTCMD_SH) bin/libsmbclient.@SHLIBEXT@ $(DESTDIR)${prefix}/lib -$(INSTALLCLIENTCMD_A) bin/libsmbclient.a $(DESTDIR)${prefix}/lib @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)${prefix}/include - -$(INSTALLCMD) include/libsmbclient.h $(DESTDIR)${prefix}/include + -$(INSTALLCMD) $(srcdir)/include/libsmbclient.h $(DESTDIR)${prefix}/include # Python extensions -- cgit From ff8d6da5a3e799ccad32add6cc2c79014c79a7ba Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 9 Apr 2003 04:38:56 +0000 Subject: forgotten merge left on disk; remove extra SAFE_FREE() (This used to be commit 4d42067cb89220a1b275bc8408c9c1ba2ef7766a) --- source3/rpc_server/srv_spoolss_nt.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 71d7530410..fec9de8990 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -8414,7 +8414,6 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1)); if (info_1 == NULL) { - SAFE_FREE(queue); return WERR_NOMEM; } @@ -8424,7 +8423,6 @@ static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uin } if (found==False) { - SAFE_FREE(queue); SAFE_FREE(info_1); /* NT treats not found as bad param... yet another bad choice */ return WERR_INVALID_PARAM; -- cgit From 80cd7c552ff95b3aa4caf79768af5b1e5c07c506 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Apr 2003 05:22:17 +0000 Subject: t_push_ucs2, t_strcmp: Run tests only once by default, rather than 10000 times. (In theory they should be pure functions....) You can specify a parameter to repeat them if you want to e.g. measure performance. (This used to be commit 92acecd28c3374abcadbff0ab9cb765411f453f4) --- source3/torture/t_push_ucs2.c | 9 ++++++--- source3/torture/t_strcmp.c | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/torture/t_push_ucs2.c b/source3/torture/t_push_ucs2.c index 86ae1b9b6c..8bfc6f7ad9 100644 --- a/source3/torture/t_push_ucs2.c +++ b/source3/torture/t_push_ucs2.c @@ -30,19 +30,22 @@ static int check_push_ucs2(const char *orig) int main(int argc, char *argv[]) { int i, ret = 0; + int count = 1; /* Needed to initialize character set */ lp_load("/dev/null", True, False, False); - if (argc != 2) { - fprintf(stderr, "usage: %s STRING1\n" + if (argc < 2) { + fprintf(stderr, "usage: %s STRING1 [COUNT]\n" "Checks that a string translated UNIX->UCS2->UNIX is unchanged\n" "Should be always 0\n", argv[0]); return 2; } + if (argc >= 3) + count = atoi(argv[2]); - for (i = 0; ((i < 10000) && (!ret)); i++) + for (i = 0; ((i < count) && (!ret)); i++) ret = check_push_ucs2(argv[1]); printf("%d\n", ret); diff --git a/source3/torture/t_strcmp.c b/source3/torture/t_strcmp.c index 1d26ad22de..47327a0e06 100644 --- a/source3/torture/t_strcmp.c +++ b/source3/torture/t_strcmp.c @@ -9,15 +9,18 @@ int main(int argc, char *argv[]) { int i, ret; + int iters = 1; - if (argc != 3) { - fprintf(stderr, "usage: %s STRING1 STRING2\n" + if (argc < 3) { + fprintf(stderr, "usage: %s STRING1 STRING2 [ITERS]\n" "Compares two strings, prints the results of StrCaseCmp\n", argv[0]); return 2; } + if (argc >= 4) + iters = atoi(argv[3]); - for (i = 0; i < 10000; i++) + for (i = 0; i < iters; i++) ret = StrCaseCmp(argv[1], argv[2]); printf("%d\n", ret); -- cgit From 5b70d850479f026267d8e7f842d4ad452a04638f Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Apr 2003 05:31:39 +0000 Subject: Set character set to default (UTF-8) before running tests. (This used to be commit b20d8b49701b532d4770197c5d08fa092234bf8e) --- source3/torture/t_strcmp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3') diff --git a/source3/torture/t_strcmp.c b/source3/torture/t_strcmp.c index 47327a0e06..bc8640ee55 100644 --- a/source3/torture/t_strcmp.c +++ b/source3/torture/t_strcmp.c @@ -11,6 +11,9 @@ int main(int argc, char *argv[]) int i, ret; int iters = 1; + /* Needed to initialize character set */ + lp_load("/dev/null", True, False, False); + if (argc < 3) { fprintf(stderr, "usage: %s STRING1 STRING2 [ITERS]\n" "Compares two strings, prints the results of StrCaseCmp\n", -- cgit From a72eafee542c2b15e1ffb369d277209b63daa0e9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 9 Apr 2003 05:52:01 +0000 Subject: Rewrite of smbcontrol - it was a bit of a mess. It should now be much nicer to use and more hackable. - converted to popt - text message destinations (except for broadcast smbd) are resolved using files in piddir so the string 'winbindd' is now a destination - added --timeout option to specify timeout value - deleted complicated handling of debug args as separate command line arguments: use shell quoting instead - deleted interactive mode as punishment for using strtok() (-: - much improved command line argument checking Some of this stuff was broken before I started (print notify, profiling) but the basics still work (ping, pool-usage, debug, debuglevel). (This used to be commit 269f838dee257ee9badcae190f2c70b898676bc5) --- source3/utils/smbcontrol.c | 1103 +++++++++++++++++++++++--------------------- 1 file changed, 573 insertions(+), 530 deletions(-) (limited to 'source3') diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 44b18d57cd..8b984d9bd1 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -1,8 +1,11 @@ /* Unix SMB/CIFS implementation. - program to send control messages to Samba processes + + Send messages to other Samba daemons + + Copyright (C) Tim Potter 2003 Copyright (C) Andrew Tridgell 1994-1998 - Copyright (C) 2001, 2002 by Martin Pool + Copyright (C) Martin Pool 2001-2002 Copyright (C) Simo Sorce 2002 This program is free software; you can redistribute it and/or modify @@ -22,678 +25,718 @@ #include "includes.h" -extern BOOL AllowDebugChange; +/* Default timeout value when waiting for replies (in seconds) */ -static const struct { - const char *name; - int value; -} msg_types[] = { - {"debug", MSG_DEBUG}, - {"force-election", MSG_FORCE_ELECTION}, - {"ping", MSG_PING}, - {"profile", MSG_PROFILE}, - {"profilelevel", MSG_REQ_PROFILELEVEL}, - {"debuglevel", MSG_REQ_DEBUGLEVEL}, - {"printnotify", MSG_PRINTER_NOTIFY2 }, - {"close-share", MSG_SMB_FORCE_TDIS}, - {"samsync", MSG_SMB_SAM_SYNC}, - {"samrepl", MSG_SMB_SAM_REPL}, - {"pool-usage", MSG_REQ_POOL_USAGE }, - {"dmalloc-mark", MSG_REQ_DMALLOC_MARK }, - {"dmalloc-log-changed", MSG_REQ_DMALLOC_LOG_CHANGED }, - {"shutdown", MSG_SHUTDOWN }, - {"drvupgrade", MSG_PRINTER_DRVUPGRADE}, - {NULL, -1} -}; +#define DEFAULT_TIMEOUT 10 -time_t timeout_start; +static int timeout = DEFAULT_TIMEOUT; +static int num_replies; /* Used by message callback fns */ -#define MAX_WAIT 10 +/* Send a message to a destination pid. Zero means broadcast smbd. */ -/* we need these because we link to printing*.o */ +static BOOL send_message(pid_t pid, int msg_type, void *buf, int len, + BOOL duplicates) +{ + TDB_CONTEXT *tdb; + BOOL ret; + int n_sent = 0; + + if (!message_init()) + return False; + + if (pid != 0) + return message_send_pid(pid, msg_type, buf, len, duplicates); + + tdb = tdb_open_log(lock_path("connections.tdb"), 0, + TDB_DEFAULT, O_RDWR, 0); + if (!tdb) { + fprintf(stderr,"Failed to open connections database" + ": %s\n", strerror(errno)); + return False; + } + + ret = message_send_all(tdb,msg_type, buf, len, duplicates, + &n_sent); + DEBUG(10,("smbcontrol/send_message: broadcast message to " + "%d processes\n", n_sent)); + + tdb_close(tdb); + + return ret; +} -void become_root(void) {} -void unbecome_root(void) {} +/* Wait for one or more reply messages */ + +static void wait_replies(BOOL multiple_replies) +{ + time_t start_time = time(NULL); + /* Wait around a bit. This is pretty disgusting - we have to + busy-wait here as there is no nicer way to do it. */ -static void usage(BOOL doexit) + do { + message_dispatch(); + if (num_replies > 0 && !multiple_replies) + break; + sleep(1); + } while (timeout - (time(NULL) - start_time) > 0); +} + +/* Message handler callback that displays a string on stdout */ + +static void print_string_cb(int msg_type, pid_t pid, void *buf, size_t len) { - int i; - if (doexit) { - printf("Usage: smbcontrol -i -s configfile\n"); - printf(" smbcontrol \n\n"); - } else { - printf(" \n\n"); + printf("%.*s", (int)len, (const char *)buf); + num_replies++; +} + +/* Send no message. Useful for testing. */ + +static BOOL do_noop(const pid_t pid, const int argc, char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol noop\n"); + return False; } - printf("\t is one of \"nmbd\", \"smbd\" or a process ID\n"); - printf("\t is one of:\n"); - for (i=0; msg_types[i].name; i++) - printf("\t\t%s\n", msg_types[i].name); - printf("\n"); - if (doexit) exit(1); + + /* Move along, nothing to see here */ + + return True; } -static int pong_count; -static BOOL got_level; -static BOOL got_pool; -static BOOL pong_registered = False; -static BOOL debuglevel_registered = False; -static BOOL poolusage_registered = False; -static BOOL profilelevel_registered = False; - - -/** - * Wait for replies for up to @p *max_secs seconds, or until @p - * max_replies are received. max_replies may be NULL in which case it - * is ignored. - * - * @note This is a pretty lame timeout; all it means is that after - * max_secs we won't look for any more messages. - **/ -static void wait_for_replies(int max_secs, int *max_replies) +/* Send a debug string */ + +static BOOL do_debug(const pid_t pid, const int argc, char **argv) { - time_t timeout_end = time(NULL) + max_secs; + if (argc != 2) { + fprintf(stderr, "Usage: smbcontrol debug " + "\n"); + return False; + } - while ((!max_replies || (*max_replies)-- > 0) - && (time(NULL) < timeout_end)) { - message_dispatch(); + return send_message( + pid, MSG_DEBUG, argv[1], strlen(argv[1]) + 1, False); +} + +/* Force a browser election */ + +static BOOL do_election(const pid_t pid, const int argc, char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol force-election\n"); + return False; } + + return send_message( + pid, MSG_FORCE_ELECTION, NULL, 0, False); } +/* Ping a samba daemon process */ -/**************************************************************************** -a useful function for testing the message system -****************************************************************************/ -void pong_function(int msg_type, pid_t src, void *buf, size_t len) +static void pong_cb(int msg_type, pid_t pid, void *buf, size_t len) { - pong_count++; - printf("PONG from PID %u\n",(unsigned int)src); + printf("PONG from pid %u\n", (unsigned int)pid); + num_replies++; } -/**************************************************************************** - Prints out the current talloc list. -****************************************************************************/ -void tallocdump_function(int msg_type, pid_t src, void *buf, size_t len) +static BOOL do_ping(const pid_t pid, const int argc, char **argv) { - char *info = (char *)buf; - - printf("Current talloc contexts for process %u\n", (unsigned int)src ); - if (len == 0) - printf("None returned\n"); - else - printf(info); - printf("\n"); - got_pool = True; + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol ping\n"); + return False; + } + + /* Send a message and register our interest in a reply */ + + if (!send_message(pid, MSG_PING, NULL, 0, False)) + return False; + + message_register(MSG_PONG, pong_cb); + + wait_replies(pid == 0); + + /* No replies were received within the timeout period */ + + if (num_replies == 0) + printf("No replies received\n"); + + message_deregister(MSG_PONG); + + return num_replies; } -/**************************************************************************** -Prints out the current Debug level returned by MSG_DEBUGLEVEL -****************************************************************************/ -void debuglevel_function(int msg_type, pid_t src, void *buf, size_t len) +/* Set profiling options */ + +static BOOL do_profile(const pid_t pid, const int argc, char **argv) { - const char *levels = (char *)buf; + int v; - printf("Current debug levels of PID %u are:\n",(unsigned int)src); - printf("%s\n", levels); - - got_level = True; + if (argc != 2) { + fprintf(stderr, "Usage: smbcontrol profile " + "\n"); + return False; + } + + if (strcmp(argv[1], "off") == 0) { + v = 0; + } else if (strcmp(argv[1], "count") == 0) { + v = 1; + } else if (strcmp(argv[1], "on") == 0) { + v = 2; + } else if (strcmp(argv[1], "flush") == 0) { + v = 3; + } else { + fprintf(stderr, "Unknown profile command '%s'\n", argv[1]); + return False; + } + + return send_message(pid, MSG_PROFILE, &v, sizeof(int), False); } -/**************************************************************************** -Prints out the current Profile level returned by MSG_PROFILELEVEL -****************************************************************************/ -void profilelevel_function(int msg_type, pid_t src, void *buf, size_t len) +/* Return the profiling level */ + +static void profilelevel_cb(int msg_type, pid_t pid, void *buf, size_t len) { - int level; - const char *s=NULL; - memcpy(&level, buf, sizeof(int)); + int level; + const char *s; + + num_replies++; + + if (len != sizeof(int)) { + fprintf(stderr, "invalid message length %d returned\n", len); + return; + } - if (level) { - switch (level) { - case 1: + memcpy(&level, buf, sizeof(int)); + + switch (level) { + case 0: + s = "not enabled"; + break; + case 1: s = "off"; break; - case 3: + case 3: s = "count only"; break; - case 7: + case 7: s = "count and time"; break; - default: - s = "BOGUS"; - break; - } - printf("Profiling %s on PID %u\n",s,(unsigned int)src); - } else { - printf("Profiling not available on PID %u\n",(unsigned int)src); + default: + s = "BOGUS"; + break; } - got_level = True; + + printf("Profiling %s on pid %u\n",s,(unsigned int)pid); } -/** - * Handle reply from POOL_USAGE. - **/ -static void pool_usage_cb(int msg_type, pid_t src_pid, void *buf, size_t len) +static void profilelevel_rqst(int msg_type, pid_t pid, void *buf, size_t len) { - printf("Got POOL_USAGE reply from pid %u:\n%.*s", - (unsigned int) src_pid, (int) len, (const char *) buf); -} + int v = 0; + + /* Send back a dummy reply */ + send_message(pid, MSG_PROFILELEVEL, &v, sizeof(int), False); +} -/** - * Send a message to a named destination - * - * @return False if an error occurred. - **/ -static BOOL send_message(char *dest, int msg_type, void *buf, int len, BOOL duplicates) +static BOOL do_profilelevel(const pid_t pid, const int argc, char **argv) { - pid_t pid; - /* "smbd" is the only broadcast operation */ - if (strequal(dest,"smbd")) { - TDB_CONTEXT *tdb; - BOOL ret; - int n_sent = 0; - - tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDWR, 0); - if (!tdb) { - fprintf(stderr,"Failed to open connections database in send_message.\n"); - return False; - } + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol profilelevel\n"); + return False; + } - ret = message_send_all(tdb,msg_type, buf, len, duplicates, - &n_sent); - DEBUG(10,("smbcontrol/send_message: broadcast message to " - "%d processes\n", n_sent)); - tdb_close(tdb); - - return ret; - } else if (strequal(dest,"nmbd")) { - pid = pidfile_pid(dest); - if (pid == 0) { - fprintf(stderr,"Can't find pid for nmbd\n"); - return False; - } - } else if (strequal(dest,"self")) { - pid = sys_getpid(); - } else { - pid = atoi(dest); - if (pid == 0) { - fprintf(stderr,"Not a valid pid\n"); - return False; - } - } + /* Send a message and register our interest in a reply */ + + if (!send_message(pid, MSG_REQ_PROFILELEVEL, NULL, 0, False)) + return False; + + message_register(MSG_PROFILELEVEL, profilelevel_cb); + message_register(MSG_REQ_PROFILELEVEL, profilelevel_rqst); - DEBUG(10,("smbcontrol/send_message: send message to pid%d\n", pid)); - return message_send_pid(pid, msg_type, buf, len, duplicates); + wait_replies(pid == 0); + + /* No replies were received within the timeout period */ + + if (num_replies == 0) + printf("No replies received\n"); + + message_deregister(MSG_PROFILE); + + return num_replies; } -/**************************************************************************** -evaluate a message type string -****************************************************************************/ -static int parse_type(char *mtype) +/* Display debug level settings */ + +static BOOL do_debuglevel(const pid_t pid, const int argc, char **argv) { - int i; - for (i=0;msg_types[i].name;i++) { - if (strequal(mtype, msg_types[i].name)) return msg_types[i].value; + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol debuglevel\n"); + return False; } - return -1; -} + /* Send a message and register our interest in a reply */ -static void register_all(void) -{ - message_register(MSG_POOL_USAGE, pool_usage_cb); -} + if (!send_message(pid, MSG_REQ_DEBUGLEVEL, NULL, 0, False)) + return False; -/* This guy is here so we can link printing/notify.c to the smbcontrol - binary without having to pull in tons of other crap. */ + message_register(MSG_DEBUGLEVEL, print_string_cb); -TDB_CONTEXT *conn_tdb_ctx(void) -{ - static TDB_CONTEXT *tdb; + wait_replies(pid == 0); - if (tdb) - return tdb; + /* No replies were received within the timeout period */ - tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0); + if (num_replies == 0) + printf("No replies received\n"); - if (!tdb) - DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n")); + message_deregister(MSG_DEBUGLEVEL); - return tdb; + return num_replies; } -/**************************************************************************** -do command -****************************************************************************/ -static BOOL do_command(char *dest, char *msg_name, int iparams, char **params) +/* Send a print notify message */ + +static BOOL do_printnotify(const pid_t pid, const int argc, char **argv) { - int i, n, v; - int mtype; - BOOL retval=False; - BOOL check_notify_msgs = False; - - mtype = parse_type(msg_name); - if (mtype == -1) { - fprintf(stderr,"Couldn't resolve message type: %s\n", msg_name); - return(False); + char *cmd; + + /* Check for subcommand */ + + if (argc == 1) { + fprintf(stderr, "Must specify subcommand:\n"); + fprintf(stderr, "\tqueuepause \n"); + fprintf(stderr, "\tqueueresume \n"); + fprintf(stderr, "\tjobpause \n"); + fprintf(stderr, "\tjobresume \n"); + fprintf(stderr, "\tjobdelete \n"); + fprintf(stderr, "\tprinter \n"); + + return False; } - switch (mtype) { - case MSG_DEBUG: { - char *buf, *b; - char **p; - int dim = 0; + cmd = argv[1]; - if (!params || !params[0]) { - fprintf(stderr,"MSG_DEBUG needs a parameter\n"); - return(False); - } + if (strcmp(cmd, "queuepause") == 0) { - /* first pass retrieve total lenght */ - for (p = params; p && *p ; p++) - dim += (strnlen(*p, 1024) +1); /* lenght + space */ - b = buf = malloc(dim); - if (!buf) { - fprintf(stderr, "Out of memory!"); - return(False); - } - /* now build a single string with all parameters */ - for(p = params; p && *p; p++) { - int l = strnlen(*p, 1024); - strncpy(b, *p, l); - b[l] = ' '; - b = b + l + 1; + if (argc != 3) { + fprintf(stderr, "Usage: smbcontrol printnotify" + " queuepause \n"); + return False; } - b[-1] = '\0'; + + notify_printer_status_byname(argv[2], PRINTER_STATUS_PAUSED); - send_message(dest, MSG_DEBUG, buf, dim, False); + goto send; - free(buf); - - break; - } + } else if (strcmp(cmd, "queueresume") == 0) { - case MSG_PROFILE: - if (!params || !params[0]) { - fprintf(stderr,"MSG_PROFILE needs a parameter\n"); - return(False); - } - if (strequal(params[0], "off")) { - v = 0; - } else if (strequal(params[0], "count")) { - v = 1; - } else if (strequal(params[0], "on")) { - v = 2; - } else if (strequal(params[0], "flush")) { - v = 3; - } else { - fprintf(stderr, - "MSG_PROFILE parameter must be off, count, on, or flush\n"); - return(False); + if (argc != 3) { + fprintf(stderr, "Usage: smbcontrol printnotify" + " queuereume \n"); + return False; } - send_message(dest, MSG_PROFILE, &v, sizeof(int), False); - break; + + notify_printer_status_byname(argv[2], PRINTER_STATUS_OK); - case MSG_FORCE_ELECTION: - if (!strequal(dest, "nmbd")) { - fprintf(stderr,"force-election can only be sent to nmbd\n"); - return(False); - } - send_message(dest, MSG_FORCE_ELECTION, NULL, 0, False); - break; + goto send; - case MSG_REQ_PROFILELEVEL: - if (!profilelevel_registered) { - message_register(MSG_PROFILELEVEL, profilelevel_function); - profilelevel_registered = True; - } - got_level = False; - retval = send_message(dest, MSG_REQ_PROFILELEVEL, NULL, 0, True); - if (retval) { - timeout_start = time(NULL); - while (!got_level) { - message_dispatch(); - if ((time(NULL) - timeout_start) > MAX_WAIT) { - fprintf(stderr,"profilelevel timeout\n"); - break; - } - } + } else if (strcmp(cmd, "jobpause") == 0) { + int jobid; + + if (argc != 4) { + fprintf(stderr, "Usage: smbcontrol printnotify" + " jobpause \n"); + return False; } - break; - case MSG_REQ_DEBUGLEVEL: - if (!debuglevel_registered) { - message_register(MSG_DEBUGLEVEL, debuglevel_function); - debuglevel_registered = True; + jobid = atoi(argv[3]); + + notify_job_status_byname( + argv[2], jobid, JOB_STATUS_PAUSED, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); + + goto send; + + } else if (strcmp(cmd, "jobresume") == 0) { + int jobid; + + if (argc != 4) { + fprintf(stderr, "Usage: smbcontrol printnotify" + " jobpause \n"); + return False; } - got_level = False; - retval = send_message(dest, MSG_REQ_DEBUGLEVEL, NULL, 0, True); - if (retval) { - timeout_start = time(NULL); - while (!got_level) { - message_dispatch(); - if ((time(NULL) - timeout_start) > MAX_WAIT) { - fprintf(stderr,"debuglevel timeout\n"); - break; - } - } + + jobid = atoi(argv[3]); + + notify_job_status_byname( + argv[2], jobid, JOB_STATUS_QUEUED, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); + + goto send; + + } else if (strcmp(cmd, "jobdelete") == 0) { + int jobid; + + if (argc != 4) { + fprintf(stderr, "Usage: smbcontrol printnotify" + " jobpause \n"); + return False; } - break; - /* Send a notification message to a printer */ + jobid = atoi(argv[3]); + + notify_job_status_byname( + argv[2], jobid, JOB_STATUS_DELETING, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); + + notify_job_status_byname( + argv[2], jobid, JOB_STATUS_DELETING| + JOB_STATUS_DELETED, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); - case MSG_PRINTER_NOTIFY2: { - char *cmd; + goto send; - /* Read subcommand */ + } else if (strcmp(cmd, "printer") == 0) { + uint32 attribute; + + if (argc != 5) { + fprintf(stderr, "Usage: smbcontrol printnotify " + "printer " + "\n"); + return False; + } - if (!params || !params[0]) { - fprintf(stderr, "Must specify subcommand:\n"); - fprintf(stderr, "\tqueuepause \n"); - fprintf(stderr, "\tqueueresume \n"); - fprintf(stderr, "\tjobpause \n"); - fprintf(stderr, "\tjobresume \n"); - fprintf(stderr, "\tjobdelete \n"); - fprintf(stderr, "\tprinter \n"); + if (strcmp(argv[3], "comment") == 0) { + attribute = PRINTER_NOTIFY_COMMENT; + } else if (strcmp(argv[3], "port") == 0) { + attribute = PRINTER_NOTIFY_PORT_NAME; + } else if (strcmp(argv[3], "driver") == 0) { + attribute = PRINTER_NOTIFY_DRIVER_NAME; + } else { + fprintf(stderr, "Invalid printer command '%s'\n", + argv[3]); return False; } - cmd = params[0]; + notify_printer_byname(argv[2], attribute, argv[4]); - check_notify_msgs = True; + goto send; + } - /* Pause a print queue */ + fprintf(stderr, "Invalid subcommand '%s'\n", cmd); + return False; - if (strequal(cmd, "queuepause")) { +send: + print_notify_send_messages(0); + return True; +} - if (!params[1]) { - fprintf(stderr, "queuepause command requires a printer name\n"); - return False; - } +/* Close a share */ - notify_printer_status_byname(params[1], PRINTER_STATUS_PAUSED); - break; - } +static BOOL do_closeshare(const pid_t pid, const int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: smbcontrol close-share " + "\n"); + return False; + } - /* Resume a print queue */ + return send_message( + pid, MSG_SMB_FORCE_TDIS, argv[1], strlen(argv[1]) + 1, False); +} - if (strequal(cmd, "queueresume")) { +/* Force a SAM synchronisation */ - if (!params[1]) { - fprintf(stderr, "queueresume command requires a printer name\n"); - return False; - } +static BOOL do_samsync(const pid_t pid, const int argc, char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol samsync\n"); + return False; + } - notify_printer_status_byname(params[1], PRINTER_STATUS_OK); - break; - } + return send_message( + pid, MSG_SMB_SAM_SYNC, NULL, 0, False); +} - /* Pause a print job */ +/* Force a SAM replication */ - if (strequal(cmd, "jobpause")) { - int jobid; +static BOOL do_samrepl(const pid_t pid, const int argc, char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol samrepl\n"); + return False; + } - if (!params[1] || !params[2]) { - fprintf(stderr, "jobpause command requires a printer name and a jobid\n"); - return False; - } + return send_message( + pid, MSG_SMB_SAM_REPL, NULL, 0, False); +} - jobid = atoi(params[2]); +/* Display talloc pool usage */ - notify_job_status_byname( - params[1], jobid, JOB_STATUS_PAUSED, - SPOOLSS_NOTIFY_MSG_UNIX_JOBID); - break; - } +static BOOL do_poolusage(const pid_t pid, const int argc, char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol pool-usage\n"); + return False; + } - /* Resume a print job */ + /* Send a message and register our interest in a reply */ - if (strequal(cmd, "jobresume")) { - int jobid; + if (!send_message(pid, MSG_REQ_POOL_USAGE, NULL, 0, False)) + return False; - if (!params[1] || !params[2]) { - fprintf(stderr, "jobresume command requires a printer name and a jobid\n"); - return False; - } + message_register(MSG_POOL_USAGE, print_string_cb); - jobid = atoi(params[2]); + wait_replies(pid == 0); - notify_job_status_byname( - params[1], jobid, JOB_STATUS_QUEUED, - SPOOLSS_NOTIFY_MSG_UNIX_JOBID); - break; - } + /* No replies were received within the timeout period */ - /* Delete a print job */ + if (num_replies == 0) + printf("No replies received\n"); - if (strequal(cmd, "jobdelete")) { - int jobid; + message_deregister(MSG_POOL_USAGE); - if (!params[1] || !params[2]) { - fprintf(stderr, "jobdelete command requires a printer name and a jobid\n"); - return False; - } + return num_replies; +} - jobid = atoi(params[2]); +/* Perform a dmalloc mark */ - notify_job_status_byname( - params[1], jobid, JOB_STATUS_DELETING, - SPOOLSS_NOTIFY_MSG_UNIX_JOBID); +static BOOL do_dmalloc_mark(const pid_t pid, const int argc, char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol dmalloc-mark\n"); + return False; + } - notify_job_status_byname( - params[1], jobid, JOB_STATUS_DELETING| - JOB_STATUS_DELETED, - SPOOLSS_NOTIFY_MSG_UNIX_JOBID); - } - - /* printer change notify */ - - if (strequal(cmd, "printer")) { - int attribute = -1; - - if (!params[1] || !params[2] || !params[3]) { - fprintf(stderr, "printer command requires an and attribute name and value!\n"); - fprintf(stderr, "supported attributes:\n"); - fprintf(stderr, "\tcomment:\n"); - fprintf(stderr, "\tport:\n"); - fprintf(stderr, "\tdriver:\n"); - return False; - } - if ( strequal(params[2], "comment") ) - attribute = PRINTER_NOTIFY_COMMENT; - else if ( strequal(params[2], "port") ) - attribute = PRINTER_NOTIFY_PORT_NAME; - else if ( strequal(params[2], "driver") ) - attribute = PRINTER_NOTIFY_DRIVER_NAME; - - if ( attribute == -1 ) { - fprintf(stderr, "bad attribute!\n"); - return False; - } - - notify_printer_byname( params[1], attribute, params[3]); - - break; - } - - break; - } + return send_message( + pid, MSG_REQ_DMALLOC_MARK, NULL, 0, False); +} +/* Perform a dmalloc changed */ - case MSG_SMB_FORCE_TDIS: - if (!strequal(dest, "smbd")) { - fprintf(stderr,"close-share can only be sent to smbd\n"); - return(False); - } - if (!params || !params[0]) { - fprintf(stderr, "close-share needs a share name or '*'\n"); - return (False); - } - retval = send_message(dest, MSG_SMB_FORCE_TDIS, params[0], - strlen(params[0]) + 1, False); - break; +static BOOL do_dmalloc_changed(const pid_t pid, const int argc, + char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol " + "dmalloc-log-changed\n"); + return False; + } - case MSG_SMB_SAM_SYNC: - if (!strequal(dest, "smbd")) { - fprintf(stderr, "samsync can only be sent to smbd\n"); - return False; - } + return send_message( + pid, MSG_REQ_DMALLOC_LOG_CHANGED, NULL, 0, False); +} - if (params) { - fprintf(stderr, "samsync does not take any parameters\n"); - return False; - } +/* Shutdown a server process */ - retval = send_message(dest, MSG_SMB_SAM_SYNC, NULL, 0, False); +static BOOL do_shutdown(const pid_t pid, const int argc, char **argv) +{ + if (argc != 1) { + fprintf(stderr, "Usage: smbcontrol shutdown\n"); + return False; + } - break; + return send_message(pid, MSG_SHUTDOWN, NULL, 0, False); +} - case MSG_SMB_SAM_REPL: { - uint32 seqnum; +/* Notify a driver upgrade */ - if (!strequal(dest, "smbd")) { - fprintf(stderr, "sam repl can only be sent to smbd\n"); - return False; - } +static BOOL do_drvupgrade(const pid_t pid, const int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: smbcontrol drvupgrade " + "\n"); + return False; + } - if (!params || !params[0]) { - fprintf(stderr, "SAM_REPL needs a parameter\n"); - return False; - } + return send_message( + pid, MSG_DEBUG, argv[1], strlen(argv[1]) + 1, False); +} - seqnum = atoi(params[0]); +/* A list of message type supported */ - retval = send_message(dest, MSG_SMB_SAM_SYNC, - (char *)&seqnum, sizeof(uint32), False); +static const struct { + const char *name; /* Option name */ + BOOL (*fn)(const pid_t pid, const int argc, char **argv); + const char *help; /* Short help text */ +} msg_types[] = { + { "debug", do_debug, "Set debuglevel" }, + { "force-election", do_election, + "Force a browse election" }, + { "ping", do_ping, "Elicit a response" }, + { "profile", do_profile, "" }, + { "profilelevel", do_profilelevel, "" }, + { "debuglevel", do_debuglevel, "Display current debuglevels" }, + { "printnotify", do_printnotify, "Send a print notify message" }, + { "close-share", do_closeshare, "Forcibly disconnect a share" }, + { "samsync", do_samsync, "Initiate SAM synchronisation" }, + { "samrepl", do_samrepl, "Initiate SAM replication" }, + { "pool-usage", do_poolusage, "Display talloc memory usage" }, + { "dmalloc-mark", do_dmalloc_mark, "" }, + { "dmalloc-log-changed", do_dmalloc_changed, "" }, + { "shutdown", do_shutdown, "Shut down daemon" }, + { "drvupgrade", do_drvupgrade, "Notify a printer driver has changed" }, + { "noop", do_noop, "Do nothing" }, + { NULL } +}; - break; - } +/* Yuck - we need these because we link to printing*.o even though + they aren't used. */ - case MSG_PING: - if (!pong_registered) { - message_register(MSG_PONG, pong_function); - pong_registered = True; - } - if (!params || !params[0]) { - fprintf(stderr,"MSG_PING needs a parameter\n"); - return(False); - } - n = atoi(params[0]); - pong_count = 0; - for (i=0;i 1) - retval = send_message(dest, MSG_PING, params[1], strlen(params[1]) + 1, True); - else - retval = send_message(dest, MSG_PING, NULL, 0, True); - if (retval == False) - return False; - } - wait_for_replies(MAX_WAIT, &n); - if (n > 0) { - fprintf(stderr,"PING timeout\n"); - } - break; +void become_root(void) {} +void unbecome_root(void) {} - case MSG_REQ_POOL_USAGE: - if (!send_message(dest, MSG_REQ_POOL_USAGE, NULL, 0, True)) - return False; - wait_for_replies(MAX_WAIT, NULL); - - break; +/* Display usage information */ - case MSG_REQ_DMALLOC_LOG_CHANGED: - case MSG_REQ_DMALLOC_MARK: - if (!send_message(dest, mtype, NULL, 0, False)) - return False; - break; +static void usage(poptContext *pc) +{ + int i; - case MSG_SHUTDOWN: - if (!send_message(dest, MSG_SHUTDOWN, NULL, 0, False)) - return False; - break; - case MSG_PRINTER_DRVUPGRADE: - if (!params || !params[0]) { - fprintf(stderr,"drvupgrade needs a parameter\n"); - return(False); - } + poptPrintHelp(*pc, stderr, 0); - if (!send_message(dest, MSG_PRINTER_DRVUPGRADE, params[0], 0, False)) - return False; - break; + fprintf(stderr, "\n"); + fprintf(stderr, " is one of \"nmbd\", \"smbd\" or a " + "process ID\n"); + + fprintf(stderr, "\n"); + fprintf(stderr, " is one of:\n"); + + for (i = 0; msg_types[i].name; i++) + fprintf(stderr, "\t%-30s%s\n", msg_types[i].name, + msg_types[i].help); + + fprintf(stderr, "\n"); + + exit(1); +} + +/* Return the pid number for a string destination */ + +static pid_t parse_dest(char *dest) +{ + pid_t pid; + + /* Zero is a special return value for broadcast smbd */ + + if (strequal(dest, "smbd")) + return 0; + + /* Try self - useful for testing */ + + if (strequal(dest, "self")) + return sys_getpid(); + + /* Check for numeric pid number */ + + if ((pid = atoi(dest)) != 0) + return pid; + + /* Look up other destinations in pidfile directory */ + + if ((pid = pidfile_pid(dest)) != 0) + return pid; + + fprintf(stderr,"Can't find pid for destination '%s'\n", dest); + + return -1; +} + +/* Execute smbcontrol command */ + +static BOOL do_command(int argc, char **argv) +{ + char *dest = argv[0], *command = argv[1]; + pid_t pid; + int i; + + /* Check destination */ + + if ((pid = parse_dest(dest)) == -1) + return False; + + /* Check command */ + + for (i = 0; msg_types[i].name; i++) { + if (strequal(command, msg_types[i].name)) + return msg_types[i].fn(pid, argc - 1, argv + 1); } - /* check if we have any pending print notify messages */ + fprintf(stderr, "smbcontrol: unknown command '%s'\n", command); - if ( check_notify_msgs ) - print_notify_send_messages(0); - - return (True); + return False; } - int main(int argc, char *argv[]) +/* Main program */ + +int main(int argc, char **argv) { + poptContext pc; int opt; - char temp[255]; - extern int optind; - BOOL interactive = False; - AllowDebugChange = False; - DEBUGLEVEL = 0; + struct poptOption wbinfo_options[] = { + { "timeout", 't', POPT_ARG_INT, &timeout, 't', + "Set timeout value in seconds", "TIMEOUT" }, + + { "configfile", 's', POPT_ARG_STRING, NULL, 's', + "Use alternative configuration file", "CONFIGFILE" }, + + POPT_TABLEEND + }; + + struct poptOption options[] = { + { NULL, 0, POPT_ARG_INCLUDE_TABLE, wbinfo_options, 0, + "Options" }, + + POPT_AUTOHELP + POPT_COMMON_VERSION + POPT_TABLEEND + }; setup_logging(argv[0],True); - if (argc < 2) usage(True); + /* Parse command line arguments using popt */ + + pc = poptGetContext( + "smbcontrol", argc, (const char **)argv, options, 0); + + poptSetOtherOptionHelp(pc, "[OPTION...] " + ""); + + if (argc == 1) + usage(&pc); - while ((opt = getopt(argc, argv,"is:")) != EOF) { - switch (opt) { - case 'i': - interactive = True; + while ((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + case 't': /* --timeout */ + argc -= 2; break; - case 's': + case 's': /* --configfile */ pstrcpy(dyn_CONFIGFILE, optarg); + argc -= 2; break; default: - printf("Unknown option %c (%d)\n", (char)opt, opt); - usage(True); + fprintf(stderr, "Invalid option\n"); + poptPrintHelp(pc, stderr, 0); + break; } } - lp_load(dyn_CONFIGFILE,False,False,False); - - if (!message_init()) exit(1); + /* We should now have the remaining command line arguments in + argv. The argc parameter should have been decremented to the + correct value in the above switch statement. */ - argc -= optind; - argv = &argv[optind]; + argv = (char **)poptGetArgs(pc); + argc--; /* Don't forget about argv[0] */ - register_all(); + if (argc == 1) + usage(&pc); - if (!interactive) { - if (argc < 2) usage(True); - /* Need to invert sense of return code -- samba - * routines mostly return True==1 for success, but - * shell needs 0. */ - return ! do_command(argv[0],argv[1], argc-2, argc > 2 ? &argv[2] : 0); - } - - while (True) { - char *myargv[4]; - int myargc; + lp_load(dyn_CONFIGFILE,False,False,False); - printf("smbcontrol> "); - if (!fgets(temp, sizeof(temp)-1, stdin)) break; - myargc = 0; - while ((myargc < 4) && - (myargv[myargc] = strtok(myargc?NULL:temp," \t\n"))) { - myargc++; - } - if (!myargc) break; - if (strequal(myargv[0],"q")) break; - if (myargc < 2) - usage(False); - else if (!do_command(myargv[0],myargv[1],myargc-2,myargc > 2 ? &myargv[2] : 0)) - usage(False); - } - return(0); + /* Need to invert sense of return code -- samba + * routines mostly return True==1 for success, but + * shell needs 0. */ + + return !do_command(argc, argv); } - -- cgit From e9c998df0898d9ceed72d013c39a23c2165d8550 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 9 Apr 2003 05:53:31 +0000 Subject: poptify smbcontrol (This used to be commit f75d4b90caa51cb2815c1be2de5f2058ec32e73d) --- source3/Makefile.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index dc0a5ccfa5..479d16fedd 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -394,8 +394,8 @@ STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ - $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) printing/notify.o \ - printing/printing_db.o + $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \ + printing/notify.o printing/printing_db.o SMBTREE_OBJ = utils/smbtree.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) \ @@ -787,9 +787,9 @@ bin/smbstatus@EXEEXT@: $(STATUS_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ -bin/smbcontrol@EXEEXT@: $(SMBCONTROL_OBJ) bin/.dummy +bin/smbcontrol@EXEEXT@: $(SMBCONTROL_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) + @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ -- cgit From a62cd3285aa0dd83aabb6d40a76d51e1eff323b6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 9 Apr 2003 05:55:33 +0000 Subject: Ignore testtmp directory. (This used to be commit 862e3ee421efc92ebfcb17eabe06efea3a64999f) --- source3/stf/.cvsignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/stf/.cvsignore b/source3/stf/.cvsignore index 7e99e367f8..bcf4150606 100644 --- a/source3/stf/.cvsignore +++ b/source3/stf/.cvsignore @@ -1 +1,2 @@ -*.pyc \ No newline at end of file +*.pyc +testtmp -- cgit From 29883705106dc433b1ff0e3bb7bdd3558430f9cf Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 9 Apr 2003 05:57:00 +0000 Subject: Tests for smbcontrol. (This used to be commit 7bf68a533ee76ffebf77c4d09abf42079579646f) --- source3/stf/smbcontrol.py | 238 +++++++++++++++++++++++++++++++++++++++++++ source3/stf/standardcheck.py | 3 +- 2 files changed, 240 insertions(+), 1 deletion(-) create mode 100755 source3/stf/smbcontrol.py (limited to 'source3') diff --git a/source3/stf/smbcontrol.py b/source3/stf/smbcontrol.py new file mode 100755 index 0000000000..30c331819c --- /dev/null +++ b/source3/stf/smbcontrol.py @@ -0,0 +1,238 @@ +#!/usr/bin/python +# +# Test for smbcontrol command line argument handling. +# + +import comfychair + +class NoArgs(comfychair.TestCase): + """Test no arguments produces usage message.""" + def runtest(self): + out = self.runcmd("smbcontrol", expectedResult = 1) + self.assert_re_match("Usage: smbcontrol", out[1]) + +class OneArg(comfychair.TestCase): + """Test single argument produces usage message.""" + def runtest(self): + out = self.runcmd("smbcontrol foo", expectedResult = 1) + self.assert_re_match("Usage: smbcontrol", out[1]) + +class SmbdDest(comfychair.TestCase): + """Test the broadcast destination 'smbd'.""" + def runtest(self): + out = self.runcmd("smbcontrol smbd noop") + +class NmbdDest(comfychair.TestCase): + """Test the destination 'nmbd'.""" + def runtest(self): + # We need a way to start/stop/whatever nmbd + raise comfychair.NotRunError, "not implemented" + +class PidDest(comfychair.TestCase): + """Test a pid number destination'.""" + def runtest(self): + out = self.runcmd("smbcontrol 1234 noop") + +class SelfDest(comfychair.TestCase): + """Test the destination 'self'.""" + def runtest(self): + out = self.runcmd("smbcontrol self noop") + +class WinbinddDest(comfychair.TestCase): + """Test the destination 'winbindd'.""" + def runtest(self): + # We need a way to start/stop/whatever winbindd + raise comfychair.NotRunError, "not implemented" + +class BadDest(comfychair.TestCase): + """Test a bad destination.""" + def runtest(self): + out = self.runcmd("smbcontrol foo noop", expectedResult = 1) + +class BadCmd(comfychair.TestCase): + """Test a bad command.""" + def runtest(self): + out = self.runcmd("smbcontrol self spottyfoot", expectedResult = 1) + self.assert_re_match("smbcontrol: unknown command", out[1]); + +class NoArgCmdTest(comfychair.TestCase): + """A test class that tests a command with no argument.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self %s" % self.cmd) + out = self.runcmd("smbcontrol self %s spottyfoot" % self.cmd, + expectedResult = 1) + +class ForceElection(NoArgCmdTest): + """Test a force-election message.""" + def setup(self): + self.cmd = "force-election" + +class SamSync(NoArgCmdTest): + """Test a samsync message.""" + def setup(self): + self.cmd = "samsync" + +class SamRepl(NoArgCmdTest): + """Test a samrepl message.""" + def setup(self): + self.cmd = "samrepl" + +class DmallocChanged(NoArgCmdTest): + """Test a dmalloc-changed message.""" + def setup(self): + self.cmd = "dmalloc-log-changed" + +class DmallocMark(NoArgCmdTest): + """Test a dmalloc-mark message.""" + def setup(self): + self.cmd = "dmalloc-mark" + +class Shutdown(NoArgCmdTest): + """Test a shutdown message.""" + def setup(self): + self.cmd = "shutdown" + +class Ping(NoArgCmdTest): + """Test a ping message.""" + def setup(self): + self.cmd = "ping" + +class Debuglevel(NoArgCmdTest): + """Test a debuglevel message.""" + def setup(self): + self.cmd = "debuglevel" + +class OneArgCmdTest(comfychair.TestCase): + """A test class that tests a command with one argument.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self %s spottyfoot" % self.cmd) + out = self.runcmd("smbcontrol self %s" % self.cmd, expectedResult = 1) + +class DrvUpgrade(OneArgCmdTest): + """Test driver upgrade message.""" + def setup(self): + self.cmd = "drvupgrade" + +class CloseShare(OneArgCmdTest): + """Test close share message.""" + def setup(self): + self.cmd = "close-share" + +class Debug(OneArgCmdTest): + """Test a debug message.""" + def setup(self): + self.cmd = "debug" + +class PrintNotify(comfychair.TestCase): + """Test print notification commands.""" + def runtest(self): + + # No subcommand + + out = self.runcmd("smbcontrol self printnotify", expectedResult = 1) + self.assert_re_match("Must specify subcommand", out[1]); + + # Invalid subcommand name + + out = self.runcmd("smbcontrol self printnotify spottyfoot", + expectedResult = 1) + self.assert_re_match("Invalid subcommand", out[1]); + + # Queue commands + + for cmd in ["queuepause", "queueresume"]: + + out = self.runcmd("smbcontrol self printnotify %s" % cmd, + expectedResult = 1) + self.assert_re_match("Usage:", out[1]) + + out = self.runcmd("smbcontrol self printnotify %s spottyfoot" + % cmd) + + # Job commands + + for cmd in ["jobpause", "jobresume", "jobdelete"]: + + out = self.runcmd("smbcontrol self printnotify %s" % cmd, + expectedResult = 1) + self.assert_re_match("Usage:", out[1]) + + out = self.runcmd("smbcontrol self printnotify %s spottyfoot" + % cmd, expectedResult = 1) + self.assert_re_match("Usage:", out[1]) + + out = self.runcmd("smbcontrol self printnotify %s spottyfoot 123" + % cmd) + + # Printer properties + + out = self.runcmd("smbcontrol self printnotify printer", + expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self printnotify printer spottyfoot", + expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + for cmd in ["comment", "port", "driver"]: + + out = self.runcmd("smbcontrol self printnotify printer spottyfoot " + "%s" % cmd, expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self printnotify printer spottyfoot " + "%s value" % cmd) + +class Profile(comfychair.TestCase): + """Test setting the profiling level.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self profile", expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self profile spottyfoot", + expectedResult = 1) + self.assert_re_match("Unknown", out[1]) + + for cmd in ["off", "count", "on", "flush"]: + out = self.runcmd("smbcontrol self profile %s" % cmd) + +class ProfileLevel(comfychair.TestCase): + """Test requesting the current profiling level.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self profilelevel spottyfoot", + expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self profilelevel") + +class TimeoutArg(comfychair.TestCase): + """Test the --timeout argument.""" + def runtest(self): + out = self.runcmd("smbcontrol --timeout 5 self noop") + out = self.runcmd("smbcontrol --timeout spottyfoot self noop", + expectedResult = 1) + +class ConfigFileArg(comfychair.TestCase): + """Test the --configfile argument.""" + def runtest(self): + out = self.runcmd("smbcontrol --configfile /dev/null self noop") + +class BogusArg(comfychair.TestCase): + """Test a bogus command line argument.""" + def runtest(self): + out = self.runcmd("smbcontrol --bogus self noop", expectedResult = 1) + +tests = [NoArgs, OneArg, SmbdDest, NmbdDest, WinbinddDest, PidDest, + SelfDest, BadDest, BadCmd, Debug, ForceElection, SamSync, + SamRepl, DmallocMark, DmallocChanged, Shutdown, DrvUpgrade, + CloseShare, Ping, Debuglevel, PrintNotify, Profile, ProfileLevel, + TimeoutArg, ConfigFileArg, BogusArg] + +# Handle execution of this file as a main program + +if __name__ == '__main__': + comfychair.main(tests) diff --git a/source3/stf/standardcheck.py b/source3/stf/standardcheck.py index 5af1c78376..bec21b8ec5 100644 --- a/source3/stf/standardcheck.py +++ b/source3/stf/standardcheck.py @@ -22,12 +22,13 @@ """These tests are run by Samba's "make check".""" import strings, comfychair +import smbcontrol # There should not be any actual tests in here: this file just serves # to define the ones run by default. They're imported from other # modules. -tests = strings.tests +tests = strings.tests + smbcontrol.tests if __name__ == '__main__': comfychair.main(tests) -- cgit From bdca5d31c3861b58f1b02371b3913f08ead8d9a6 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Apr 2003 06:01:15 +0000 Subject: Ignore .po and .po32 files. (This used to be commit f01d94b027e0ca1530b2e50782a34c22706c643c) --- source3/groupdb/.cvsignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 source3/groupdb/.cvsignore (limited to 'source3') diff --git a/source3/groupdb/.cvsignore b/source3/groupdb/.cvsignore new file mode 100644 index 0000000000..22beab949c --- /dev/null +++ b/source3/groupdb/.cvsignore @@ -0,0 +1,2 @@ +.po +.po32 -- cgit From 1c2e2ba39ea03bec900db58a90803df95a91c73f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 9 Apr 2003 06:02:56 +0000 Subject: another forgotten merge sitting on my laptop from app_head; only stall open_printer when 2k client opens with admin privs & fix reply for ChangeId printer data reply (This used to be commit c7c3d42cd5954b040ee7027886ea8d9d0f2da9a5) --- source3/rpc_server/srv_spoolss_nt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index fec9de8990..9f943f036a 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -1768,8 +1768,11 @@ Can't find printer handle we created for printer %s\n", name )); /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN optimization in Windows 2000 clients --jerry */ - if ( RA_WIN2K == get_remote_arch() ) - usleep( 384000 ); + if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) + && (RA_WIN2K == get_remote_arch()) ) + { + usleep( 500000 ); + } return WERR_OK; } @@ -2463,7 +2466,7 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO status = WERR_NOMEM; goto done; } - **data = printer->info_2->changeid; + SIVAL( *data, 0, printer->info_2->changeid ); status = WERR_OK; } else -- cgit From 91c9960ebabe44b144a4757b8400aef3614827aa Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Apr 2003 06:05:12 +0000 Subject: bin/smbcontrol needs to be built to run tpot's new tests of it. (This used to be commit 16b09179152748abbfb7894d328890991f6e8c57) --- source3/Makefile.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 479d16fedd..cf8791a9a8 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1341,5 +1341,7 @@ check: check-programs PATH="`pwd`/bin:$$PATH" \ python stf/standardcheck.py -# These are called by the test suite -check-programs: bin/t_strcmp bin/t_push_ucs2 +# These are called by the test suite and need to be built before +# running it. For the time being we don't build all of BIN_PROGS, +# because they're not all needed. +check-programs: bin/t_strcmp bin/t_push_ucs2 bin/smbcontrol -- cgit From 1e9be586c8b59240cd3a4b583543972f89bdaa54 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Apr 2003 06:50:59 +0000 Subject: StrCaseCmp tests: Add some tests in Katakana. Convert strings to UTF-8 before passing to test harness. (This used to be commit 79b292de98208571e49648cf88d9b565396151be) --- source3/stf/strings.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/stf/strings.py b/source3/stf/strings.py index 4e070c0444..328849b1ce 100755 --- a/source3/stf/strings.py +++ b/source3/stf/strings.py @@ -62,10 +62,10 @@ class PushUCS2_Tests(comfychair.TestCase): self.assert_equal(out, "0\n") -class StrCaseCmp_Ascii_Tests(comfychair.TestCase): +class StrCaseCmp(comfychair.TestCase): """String comparisons in simple ASCII""" def run_strcmp(self, a, b, expect): - out, err = self.runcmd('t_strcmp \"%s\" \"%s\"' % (a, b)) + out, err = self.runcmd('t_strcmp \"%s\" \"%s\"' % (a.encode('utf-8'), b.encode('utf-8'))) if signum(int(out)) != expect: self.fail("comparison failed:\n" " a=%s\n" @@ -88,12 +88,14 @@ class StrCaseCmp_Ascii_Tests(comfychair.TestCase): ('longstring ' * 100, 'longstring ' * 100, 0), ('longstring ' * 100, 'longstring ' * 100 + 'a', -1), ('longstring ' * 100 + 'a', 'longstring ' * 100, +1), + (KATAKANA_LETTER_A, KATAKANA_LETTER_A, 0), + (KATAKANA_LETTER_A, 'a', 1), ] for a, b, expect in cases: self.run_strcmp(a, b, expect) # Define the tests exported by this module -tests = [StrCaseCmp_Ascii_Tests, +tests = [StrCaseCmp, PushUCS2_Tests] # Handle execution of this file as a main program -- cgit From 786564f2b4de78c1b9f9fea7dbb5d8cbe593f27c Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Apr 2003 07:34:49 +0000 Subject: unix_strupper, unix_strlower: Remove fixed-length static buffer that makes these functions fail for strings over 512 characters. Now we use convert_string_allocate, which grows a buffer as necessary. (This used to be commit a55dc493ca212bde22d9e68ea8a4cc16a142c69d) --- source3/lib/charcnv.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index d727628e41..7acb7147fd 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -4,6 +4,7 @@ Copyright (C) Igor Vergeichik 2001 Copyright (C) Andrew Tridgell 2001 Copyright (C) Simo Sorce 2001 + Copyright (C) Martin Pool 2003 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 @@ -37,7 +38,6 @@ * @sa lib/iconv.c */ -static pstring cvtbuf; static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS]; @@ -193,7 +193,7 @@ size_t convert_string(charset_t from, charset_t to, **/ size_t convert_string_allocate(charset_t from, charset_t to, - void const *src, size_t srclen, void **dest) + void const *src, size_t srclen, void **dest) { size_t i_len, o_len, destlen; size_t retval; @@ -277,6 +277,8 @@ static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t t void *alloced_string; size_t dest_len; + /* FIXME: Ridiculous to allocate two buffers and then copy the string! */ + *dest = NULL; dest_len=convert_string_allocate(from, to, src, srclen, &alloced_string); if (dest_len == (size_t)-1) @@ -291,21 +293,40 @@ static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t t size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) { size_t size; - smb_ucs2_t *buffer=(smb_ucs2_t*)cvtbuf; - size=convert_string(CH_UNIX, CH_UCS2, src, srclen, buffer, sizeof(cvtbuf)); - if (!strupper_w(buffer) && (dest == src)) + smb_ucs2_t *buffer; + + size = convert_string_allocate(CH_UNIX, CH_UCS2, src, srclen, + (void **) &buffer); + if (size == -1) { + smb_panic("failed to create UCS2 buffer"); + } + if (!strupper_w(buffer) && (dest == src)) { + free(buffer); return srclen; - return convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); + } + + size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); + free(buffer); + return size; } size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) { size_t size; - smb_ucs2_t *buffer=(smb_ucs2_t*)cvtbuf; - size=convert_string(CH_UNIX, CH_UCS2, src, srclen, buffer, sizeof(cvtbuf)); - if (!strlower_w(buffer) && (dest == src)) + smb_ucs2_t *buffer; + + size = convert_string_allocate(CH_UNIX, CH_UCS2, src, srclen, + (void **) &buffer); + if (size == -1) { + smb_panic("failed to create UCS2 buffer"); + } + if (!strlower_w(buffer) && (dest == src)) { + free(buffer); return srclen; - return convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); + } + size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); + free(buffer); + return size; } -- cgit From 425797700b24c14c252389c2ff6cf3b569d7ee22 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 09:29:47 +0000 Subject: Put the core schannel functions to parse_prs.c. They are also used by schannel clients. Volker (This used to be commit 41e92409e1c6912db05acc80b6c0d5dccd51859b) --- source3/rpc_parse/parse_prs.c | 182 ++++++++++++++++++++++++++++++++++++++++ source3/rpc_server/srv_pipe.c | 189 +----------------------------------------- 2 files changed, 184 insertions(+), 187 deletions(-) (limited to 'source3') diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index aeaa42ac92..a22ae1bacd 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1330,3 +1330,185 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]) return True; } + +static void netsechash(uchar * key, uchar * data, int data_len) +{ + uchar hash[256]; + uchar index_i = 0; + uchar index_j = 0; + uchar j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + hash[ind] = (uchar) ind; + } + + for (ind = 0; ind < 256; ind++) + { + uchar tc; + + j += (hash[ind] + key[ind % 16]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + for (ind = 0; ind < data_len; ind++) + { + uchar tc; + uchar t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] ^= hash[t]; + } +} + +void dump_data_pw(const char *msg, const uchar * data, size_t len) +{ +#ifdef DEBUG_PASSWORD + DEBUG(11, ("%s", msg)); + if (data != NULL && len > 0) + { + dump_data(11, data, len); + } +#endif +} + +void netsec_encode(struct netsec_auth_struct *a, + RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) +{ + uchar dataN[4]; + uchar digest1[16]; + struct MD5Context ctx3; + uchar sess_kf0[16]; + int i; + + /* store the sequence number */ + SIVAL(dataN, 0, a->seq_num); + + for (i = 0; i < sizeof(sess_kf0); i++) + { + sess_kf0[i] = a->sess_key[i] ^ 0xf0; + } + + dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); + dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); + + MD5Init(&ctx3); + MD5Update(&ctx3, dataN, 0x4); + MD5Update(&ctx3, verf->sig, 8); + + MD5Update(&ctx3, verf->data8, 8); + + dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); + dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); + + hmac_md5(sess_kf0, dataN, 0x4, digest1); + dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); + hmac_md5(digest1, verf->data3, 8, digest1); + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + netsechash(digest1, verf->data8, 8); + + dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); + + dump_data_pw("data :\n", data, data_len); + MD5Update(&ctx3, data, data_len); + + { + char digest_tmp[16]; + char digest2[16]; + MD5Final(digest_tmp, &ctx3); + hmac_md5(a->sess_key, digest_tmp, 16, digest2); + dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); + dump_data_pw("digest:\n", digest2, sizeof(digest2)); + memcpy(verf->data1, digest2, sizeof(verf->data1)); + } + + netsechash(digest1, data, data_len); + dump_data_pw("data:\n", data, data_len); + + hmac_md5(a->sess_key, dataN, 0x4, digest1); + dump_data_pw("ctx:\n", digest1, sizeof(digest1)); + + hmac_md5(digest1, verf->data1, 8, digest1); + + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + + dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); + netsechash(digest1, verf->data3, 8); + dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); + + return; +} + +BOOL netsec_decode(struct netsec_auth_struct *a, + RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) +{ + uchar dataN[4]; + uchar digest1[16]; + struct MD5Context ctx3; + uchar sess_kf0[16]; + int i; + + /* store the sequence number */ + SIVAL(dataN, 0, a->seq_num); + + for (i = 0; i < sizeof(sess_kf0); i++) + { + sess_kf0[i] = a->sess_key[i] ^ 0xf0; + } + + dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); + dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); + hmac_md5(a->sess_key, dataN, 0x4, digest1); + dump_data_pw("ctx:\n", digest1, sizeof(digest1)); + + hmac_md5(digest1, verf->data1, 8, digest1); + + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); + netsechash(digest1, verf->data3, 8); + dump_data_pw("verf->data3_dec:\n", verf->data3, sizeof(verf->data3)); + + MD5Init(&ctx3); + MD5Update(&ctx3, dataN, 0x4); + MD5Update(&ctx3, verf->sig, 8); + + dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); + + hmac_md5(sess_kf0, dataN, 0x4, digest1); + dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); + hmac_md5(digest1, verf->data3, 8, digest1); + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + + dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); + netsechash(digest1, verf->data8, 8); + dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8)); + MD5Update(&ctx3, verf->data8, 8); + + dump_data_pw("data :\n", data, data_len); + netsechash(digest1, data, data_len); + dump_data_pw("datadec:\n", data, data_len); + + MD5Update(&ctx3, data, data_len); + { + uchar digest_tmp[16]; + MD5Final(digest_tmp, &ctx3); + hmac_md5(a->sess_key, digest_tmp, 16, digest1); + dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); + } + + dump_data_pw("digest:\n", digest1, sizeof(digest1)); + dump_data_pw("verf->data1:\n", verf->data1, sizeof(verf->data1)); + + return memcmp(digest1, verf->data1, sizeof(verf->data1)) == 0; +} diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9425ccbe4d..43fbb4edaa 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -284,13 +284,10 @@ BOOL create_next_pdu(pipes_struct *p) init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, sign, nullbytes); - if (!netsec_encode(&p->netsec_auth, &verf, data, data_len)) { - DEBUG(0,("create_next_pdu: failed encode data.\n")); - prs_mem_free(&outgoing_pdu); - return False; - } + netsec_encode(&p->netsec_auth, &verf, data, data_len); smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0); + p->netsec_auth.seq_num++; } @@ -1269,188 +1266,6 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) return True; } -static void netsechash(uchar * key, uchar * data, int data_len) -{ - uchar hash[256]; - uchar index_i = 0; - uchar index_j = 0; - uchar j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - hash[ind] = (uchar) ind; - } - - for (ind = 0; ind < 256; ind++) - { - uchar tc; - - j += (hash[ind] + key[ind % 16]); - - tc = hash[ind]; - hash[ind] = hash[j]; - hash[j] = tc; - } - - for (ind = 0; ind < data_len; ind++) - { - uchar tc; - uchar t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] ^= hash[t]; - } -} - -void dump_data_pw(const char *msg, const uchar * data, size_t len) -{ -#ifdef DEBUG_PASSWORD - DEBUG(11, ("%s", msg)); - if (data != NULL && len > 0) - { - dump_data(11, data, len); - } -#endif -} - -BOOL netsec_encode(struct netsec_auth_struct *a, - RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) -{ - uchar dataN[4]; - uchar digest1[16]; - struct MD5Context ctx3; - uchar sess_kf0[16]; - int i; - - /* store the sequence number */ - SIVAL(dataN, 0, a->seq_num); - - for (i = 0; i < sizeof(sess_kf0); i++) - { - sess_kf0[i] = a->sess_key[i] ^ 0xf0; - } - - dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); - dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); - - MD5Init(&ctx3); - MD5Update(&ctx3, dataN, 0x4); - MD5Update(&ctx3, verf->sig, 8); - - MD5Update(&ctx3, verf->data8, 8); - - dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); - dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); - - hmac_md5(sess_kf0, dataN, 0x4, digest1); - dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); - hmac_md5(digest1, verf->data3, 8, digest1); - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - netsechash(digest1, verf->data8, 8); - - dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); - - dump_data_pw("data :\n", data, data_len); - MD5Update(&ctx3, data, data_len); - - { - char digest_tmp[16]; - char digest2[16]; - MD5Final(digest_tmp, &ctx3); - hmac_md5(a->sess_key, digest_tmp, 16, digest2); - dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); - dump_data_pw("digest:\n", digest2, sizeof(digest2)); - memcpy(verf->data1, digest2, sizeof(verf->data1)); - } - - netsechash(digest1, data, data_len); - dump_data_pw("data:\n", data, data_len); - - hmac_md5(a->sess_key, dataN, 0x4, digest1); - dump_data_pw("ctx:\n", digest1, sizeof(digest1)); - - hmac_md5(digest1, verf->data1, 8, digest1); - - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - - dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); - netsechash(digest1, verf->data3, 8); - dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); - - return True; -} - -BOOL netsec_decode(struct netsec_auth_struct *a, - RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) -{ - uchar dataN[4]; - uchar digest1[16]; - struct MD5Context ctx3; - uchar sess_kf0[16]; - int i; - - /* store the sequence number */ - SIVAL(dataN, 0, a->seq_num); - - for (i = 0; i < sizeof(sess_kf0); i++) - { - sess_kf0[i] = a->sess_key[i] ^ 0xf0; - } - - dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); - dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); - hmac_md5(a->sess_key, dataN, 0x4, digest1); - dump_data_pw("ctx:\n", digest1, sizeof(digest1)); - - hmac_md5(digest1, verf->data1, 8, digest1); - - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); - netsechash(digest1, verf->data3, 8); - dump_data_pw("verf->data3_dec:\n", verf->data3, sizeof(verf->data3)); - - MD5Init(&ctx3); - MD5Update(&ctx3, dataN, 0x4); - MD5Update(&ctx3, verf->sig, 8); - - dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); - - hmac_md5(sess_kf0, dataN, 0x4, digest1); - dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); - hmac_md5(digest1, verf->data3, 8, digest1); - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - - dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); - netsechash(digest1, verf->data8, 8); - dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8)); - MD5Update(&ctx3, verf->data8, 8); - - dump_data_pw("data :\n", data, data_len); - netsechash(digest1, data, data_len); - dump_data_pw("datadec:\n", data, data_len); - - MD5Update(&ctx3, data, data_len); - { - uchar digest_tmp[16]; - MD5Final(digest_tmp, &ctx3); - hmac_md5(a->sess_key, digest_tmp, 16, digest1); - dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); - } - - dump_data_pw("digest:\n", digest1, sizeof(digest1)); - dump_data_pw("verf->data1:\n", verf->data1, sizeof(verf->data1)); - - return memcmp(digest1, verf->data1, sizeof(verf->data1)) == 0; -} - /**************************************************************************** Deal with schannel processing on an RPC request. ****************************************************************************/ -- cgit From d9440df5799a80357bcc51d1a8bf83f71b7f5cd9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 09:52:57 +0000 Subject: A little clarification in the rpc auth header struct. Volker (This used to be commit 9fc3e4bf9fa7845b5d4a7eb4cacfec586045ebd0) --- source3/include/rpc_dce.h | 7 +++---- source3/rpc_parse/parse_rpc.c | 15 +++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'source3') diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index 7e8bc3949e..22dae7ce36 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -197,10 +197,10 @@ typedef struct rpc_hdr_auth_info { uint8 auth_type; /* 0x0a */ uint8 auth_level; /* 0x06 */ - uint8 stub_type_len; /* don't know */ - uint8 padding; /* padding */ + uint8 padding; + uint8 reserved; /* padding */ - uint32 unknown; /* pointer */ + uint32 auth_context; /* pointer */ } RPC_HDR_AUTH; @@ -229,7 +229,6 @@ typedef struct rpc_auth_netsec_chk_info struct netsec_auth_struct { - RPC_AUTH_NETSEC_NEG netsec_neg; uchar sess_key[16]; uint32 seq_num; }; diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index baa70ae137..700ce8cfd6 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -607,15 +607,15 @@ BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai) void init_rpc_hdr_auth(RPC_HDR_AUTH *rai, uint8 auth_type, uint8 auth_level, - uint8 stub_type_len, + uint8 padding, uint32 ptr) { rai->auth_type = auth_type; /* nt lm ssp 0x0a */ rai->auth_level = auth_level; /* 0x06 */ - rai->stub_type_len = stub_type_len; /* 0x00 */ - rai->padding = 0; /* padding 0x00 */ + rai->padding = padding; + rai->reserved = 0; - rai->unknown = ptr; /* non-zero pointer to something */ + rai->auth_context = ptr; /* non-zero pointer to something */ } /******************************************************************* @@ -637,12 +637,11 @@ BOOL smb_io_rpc_hdr_auth(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, in return False; if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */ return False; - if(!prs_uint8 ("stub_type_len", ps, depth, &rai->stub_type_len)) - return False; if(!prs_uint8 ("padding ", ps, depth, &rai->padding)) return False; - - if(!prs_uint32("unknown ", ps, depth, &rai->unknown)) /* 0x0014a0c0 */ + if(!prs_uint8 ("reserved ", ps, depth, &rai->reserved)) + return False; + if(!prs_uint32("auth_context ", ps, depth, &rai->auth_context)) return False; return True; -- cgit From a6e09de2fb4e525dd2eeb4df44709cb6117fe8bc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 10:09:32 +0000 Subject: Auth2, not also Auth3 sends us flags back, although all the callers ignore it. Volker (This used to be commit 6ac6b0f4c0df9e09644d8c1f1272c8645642e842) --- source3/rpc_client/cli_netlogon.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index f83571af03..ae76e46c6d 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -85,7 +85,7 @@ encrypt of the server challenge originally received. JRA. NTSTATUS cli_net_auth2(struct cli_state *cli, uint16 sec_chan, - uint32 neg_flags, DOM_CHAL *srv_chal) + uint32 *neg_flags, DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; NET_Q_AUTH_2 q; @@ -104,7 +104,7 @@ NTSTATUS cli_net_auth2(struct cli_state *cli, /* store the parameters */ init_q_auth_2(&q, cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname(), &cli->clnt_cred.challenge, - neg_flags); + *neg_flags); /* turn parameters into data stream */ @@ -141,6 +141,7 @@ password ?).\n", cli->desthost )); result = NT_STATUS_ACCESS_DENIED; goto done; } + *neg_flags = r.srv_flgs.neg_flags; } done: @@ -195,7 +196,6 @@ NTSTATUS cli_net_auth3(struct cli_state *cli, } result = r.status; - *neg_flags = r.srv_flgs.neg_flags; if (NT_STATUS_IS_OK(result)) { UTIME zerotime; @@ -217,6 +217,7 @@ password ?).\n", cli->desthost )); result = NT_STATUS_ACCESS_DENIED; goto done; } + *neg_flags = r.srv_flgs.neg_flags; } done: @@ -286,7 +287,7 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, */ switch (level) { case 2: - result = cli_net_auth2(cli, sec_chan, *neg_flags, &srv_chal); + result = cli_net_auth2(cli, sec_chan, neg_flags, &srv_chal); break; case 3: result = cli_net_auth3(cli, sec_chan, neg_flags, &srv_chal); -- cgit From 291e8e4589308938042d86bbc858a421bc29c2a0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 9 Apr 2003 14:35:14 +0000 Subject: Use fprintf(f, ...) instead of plain printf() - patch by Ronan Waide (This used to be commit 49926d706f9d24dbdd7a878e2362a27667175a5c) --- source3/utils/smbcacls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 562fd9943f..9d8a657726 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -406,7 +406,7 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd) fstring sidstr; uint32 i; - printf("REVISION:%d\n", sd->revision); + fprintf(f, "REVISION:%d\n", sd->revision); /* Print owner and group sid */ @@ -416,7 +416,7 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd) fstrcpy(sidstr, ""); } - printf("OWNER:%s\n", sidstr); + fprintf(f, "OWNER:%s\n", sidstr); if (sd->grp_sid) { SidToString(sidstr, sd->grp_sid); -- cgit From 3ae879a4d3e0eeb85a17d2e7ebb9d1d78a442870 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 9 Apr 2003 14:49:34 +0000 Subject: Fix double free on error and typo (This used to be commit 84b116f9c007c0f933af82462dff4324ffa53f0f) --- source3/passdb/pdb_ldap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index eaef7f37a7..edae69f2cd 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -782,7 +782,7 @@ static BOOL init_ldap_from_sam (struct smb_ldap_privates *ldap_state, rid = ldapsam_get_next_available_nua_rid(ldap_state); if (rid == 0) { DEBUG(0, ("NO user RID specified on account %s, and " - "findining next available NUA RID failed, " + "finding next available NUA RID failed, " "cannot store!\n", pdb_get_username(sampass))); ldap_mods_free(*mods, 1); @@ -1520,7 +1520,6 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO element_is_set_or_changed)) { DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n")); ldap_msgfree(result); - ldap_mods_free(mods, 1); return NT_STATUS_UNSUCCESSFUL; } -- cgit From 83479a9dc9affb36ea14e701ee8847195c6b8f7f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 9 Apr 2003 15:34:12 +0000 Subject: no needed anymore (This used to be commit 8fd9450c8363021e23256903578fabbf77083978) --- source3/include/vt_mode.h | 48 ----------------------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 source3/include/vt_mode.h (limited to 'source3') diff --git a/source3/include/vt_mode.h b/source3/include/vt_mode.h deleted file mode 100644 index 85b481122e..0000000000 --- a/source3/include/vt_mode.h +++ /dev/null @@ -1,48 +0,0 @@ -/* vt_mode.h */ -/* -support vtp-sessions - -written by Christian A. Lademann -*/ - -/* -02.05.95:cal:ported to samba-1.9.13 -*/ - -#ifndef __vt_mode_h__ -# define __vt_mode_h__ - -# define VT_CLOSED 0 -# define VT_OPEN 1 - -# define MS_NONE 0 -# define MS_PTY 1 -# define MS_STREAM 2 -# define MS_VTY 3 - -# define VT_MAXREAD 32 - - -# undef EXTERN - -# ifndef __vt_mode_c__ -# define EXTERN extern -# define DEFAULT(v) -# else -# define EXTERN -# define DEFAULT(v) =(v) -# endif - - EXTERN int VT_Status DEFAULT(VT_CLOSED), - VT_Fd DEFAULT(-1), - VT_ChildPID DEFAULT(-1); - - EXTERN BOOL VT_Mode DEFAULT(False), - VT_ChildDied DEFAULT(False); - - EXTERN char *VT_Line DEFAULT(NULL); - -# undef EXTERN - - -#endif /* __vt_mode_h__ */ -- cgit From 803e23f403bdb38d2523d73fd12083da486bca2f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 15:47:06 +0000 Subject: This is the netlogon schannel client code. Try a rpcclient -S pdc -U% -c "samlogon user password" and it should work with the schannel. Needs testing platforms different from NT4SP6. Volker (This used to be commit ecd0ee4d248e750168597ccf79c389513bb0f740) --- source3/include/client.h | 6 + source3/include/smb.h | 2 + source3/libsmb/clientgen.c | 1 + source3/param/loadparm.c | 4 + source3/rpc_client/cli_pipe.c | 323 ++++++++++++++++++++++++++++++++++++--- source3/rpc_parse/parse_rpc.c | 20 ++- source3/rpcclient/cmd_netlogon.c | 19 --- source3/rpcclient/rpcclient.c | 23 ++- source3/utils/net_rpc_samsync.c | 18 +-- 9 files changed, 362 insertions(+), 54 deletions(-) (limited to 'source3') diff --git a/source3/include/client.h b/source3/include/client.h index 0ea793de68..d75effd7d0 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -132,6 +132,12 @@ struct cli_state { */ uint16 nt_pipe_fnum; /* Pipe handle. */ + + uint16 saved_netlogon_pipe_fnum; /* The "first" pipe to get + the session key for the + schannel. */ + struct netsec_auth_struct auth_info; + unsigned char sess_key[16]; /* Current session key. */ unsigned char ntlmssp_hash[258]; /* ntlmssp data. */ uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 3bb6bf9237..78690cd524 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -188,6 +188,8 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN]; #define PIPE_SPOOLSS "\\PIPE\\spoolss" #define PIPE_NETDFS "\\PIPE\\netdfs" +#define PIPE_NETLOGON_PLAIN "\\NETLOGON" + #define PI_LSARPC 0 #define PI_LSARPC_DS 1 #define PI_SAMR 2 diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fe9453e6f2..81cb61d757 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -282,6 +282,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); cli->nt_pipe_fnum = 0; + cli->saved_netlogon_pipe_fnum = 0; cli->initialised = 1; cli->allocated = alloced_cli; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index dc45fd9f5b..6a4f15bd6e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -242,6 +242,7 @@ typedef struct BOOL bDomainLogons; BOOL bEncryptPasswords; BOOL bUpdateEncrypt; + int clientSchannel; int serverSchannel; BOOL bStripDot; BOOL bNullPasswords; @@ -751,6 +752,7 @@ static struct parm_struct parm_table[] = { {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, + {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC}, {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC}, {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, @@ -1354,6 +1356,7 @@ static void init_globals(void) Globals.paranoid_server_security = True; Globals.bEncryptPasswords = True; Globals.bUpdateEncrypt = False; + Globals.clientSchannel = Auto; Globals.serverSchannel = Auto; Globals.bReadRaw = True; Globals.bWriteRaw = True; @@ -1693,6 +1696,7 @@ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions) FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot) FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords) FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt) +FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel) FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel) FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly) FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bbbf194fbd..c4a9b37127 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -191,6 +191,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int BOOL auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); BOOL auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); + BOOL auth_schannel = (cli->saved_netlogon_pipe_fnum != 0); DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n", len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal))); @@ -293,6 +294,48 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int } cli->ntlmssp_seq_num++; } + + if (auth_schannel) { + RPC_AUTH_NETSEC_CHK chk; + char data[RPC_AUTH_NETSEC_CHK_LEN]; + char *dp = prs_data_p(rdata) + len - auth_len; + prs_struct auth_verf; + + if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + DEBUG(0,("rpc_auth_pipe: wrong auth len %d\n", auth_len)); + return False; + } + + if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { + DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); + return False; + } + + DEBUG(10,("rpc_auth_pipe: verify netsec\n")); + dump_data(100, dp, auth_len); + + memcpy(data, dp, sizeof(data)); + dump_data(100, data, sizeof(data)); + + prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL); + + /* The endinness must be preserved. JRA. */ + prs_set_endian_data( &auth_verf, rdata->bigendian_data); + + prs_give_memory(&auth_verf, data, RPC_AUTH_NETSEC_CHK_LEN, False); + + if (!smb_io_rpc_auth_netsec_chk("auth_sign", &chk, &auth_verf, 0)) { + DEBUG(0, ("rpc_auth_pipe: unmarshalling " + "RPC_AUTH_NETSECK_CHK failed\n")); + return False; + } + + if (!netsec_decode(&cli->auth_info, &chk, reply_data, data_len)) { + DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); + return False; + } + cli->auth_info.seq_num++; + } return True; } @@ -542,7 +585,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd ********************************************************************/ -static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_call_id, +static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netsec, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, const char *my_name, const char *domain, uint32 neg_flags) { @@ -596,6 +639,43 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN; } + if (do_netsec) { + RPC_HDR_AUTH hdr_auth; + RPC_AUTH_NETSEC_NEG netsec_neg; + + /* + * Create the auth structs we will marshall. + */ + + init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, + 0x00, 1); + init_rpc_auth_netsec_neg(&netsec_neg, my_name, domain); + + /* + * Use the 4k buffer to store the auth info. + */ + + prs_give_memory( &auth_info, buffer, sizeof(buffer), False); + + /* + * Now marshall the data into the temporary parse_struct. + */ + + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) { + DEBUG(0,("Failed to marshall RPC_HDR_AUTH.\n")); + return False; + } + + if(!smb_io_rpc_auth_netsec_neg("netsec_neg", + &netsec_neg, &auth_info, 0)) { + DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n")); + return False; + } + + /* Auth len in the rpc header doesn't include auth_header. */ + auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN; + } + /* create the request RPC_HDR */ init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info), @@ -747,9 +827,9 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len */ if (auth_len != 0) - alloc_hint = data_left - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; + alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; else - alloc_hint = data_left - RPC_HEADER_LEN; + alloc_hint = data_len - RPC_HEADER_LEN; DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n", data_len, auth_len, alloc_hint)); @@ -771,10 +851,10 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len } /******************************************************************* - Puts an auth header into an rpc request. + Puts an NTLMSSP auth header into an rpc request. ********************************************************************/ -static BOOL create_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify) +static BOOL create_ntlmssp_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify) { RPC_HDR_AUTH hdr_auth; @@ -789,6 +869,24 @@ static BOOL create_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify) return True; } +/******************************************************************* + Puts a NETLOGON schannel auth header into an rpc request. + ********************************************************************/ + +static BOOL create_netsec_auth_hdr(prs_struct *outgoing_packet, int padding) +{ + RPC_HDR_AUTH hdr_auth; + + init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, + NETSEC_AUTH_LEVEL, padding, 1); + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, + outgoing_packet, 0)) { + DEBUG(0,("create_auth_hdr:Failed to marshal RPC_HDR_AUTH.\n")); + return False; + } + return True; +} + /******************************************************************* Puts auth data into an rpc request. ********************************************************************/ @@ -825,19 +923,26 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, { uint32 auth_len, max_data, data_left, data_sent; BOOL ret = False; - BOOL auth_verify, auth_seal; + BOOL auth_verify, auth_seal, auth_schannel; fstring dump_name; auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); + auth_schannel = (cli->saved_netlogon_pipe_fnum != 0); + + auth_len = 0; - auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0); + if (auth_verify) + auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; + + if (auth_schannel) + auth_len = RPC_AUTH_NETSEC_CHK_LEN; /* * calc how much actual data we can send in a PDU fragment */ max_data = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - - (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len; + (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len - 8; for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) { prs_struct outgoing_packet; @@ -845,13 +950,28 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, uint8 flags = 0; uint32 crc32 = 0; uint32 callid = 0; + uint32 auth_padding = 0; + RPC_AUTH_NETSEC_CHK verf; /* * how much will we send this time */ send_size = MIN(data_left, max_data); + + /* + * NT expects the data that is sealed to be 8-byte + * aligned. The padding must be encrypted as well and + * taken into account when generating the + * authentication verifier. The amount of padding must + * be stored in the auth header. + */ + + if (auth_schannel) + auth_padding = 8 - (send_size & 7); + data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size + - (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len; + ((auth_verify|auth_schannel) ? RPC_HDR_AUTH_LEN : 0) + + auth_len + auth_padding; /* * Malloc parse struct to hold it (and enough for alignments). @@ -891,18 +1011,65 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, /* * Now copy the data into the outgoing packet. */ - if(!prs_append_some_prs_data(&outgoing_packet, data, - data_sent, send_size)) { - DEBUG(0,("rpc_api_pipe_req: Failed to append data to outgoing packet.\n")); - prs_mem_free(&outgoing_packet); - return False; + + if (auth_schannel) { + static const uchar netsec_sig[8] = NETSEC_SIGNATURE; + static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; + uchar sign[8]; + BOOL ret; + int i; + prs_struct netsec_blob; + + memset(sign, 0, sizeof(sign)); + sign[4] = 0x80; + + if (!prs_init(&netsec_blob, send_size+auth_padding, + cli->mem_ctx, MARSHALL)) { + DEBUG(0,("Could not malloc %u bytes", + send_size+auth_padding)); + prs_mem_free(&outgoing_packet); + return False; + } + + if(!prs_append_some_prs_data(&netsec_blob, data, + data_sent, send_size)) { + DEBUG(0,("Failed to append data to netsec blob\n")); + prs_mem_free(&outgoing_packet); + return False; + } + + netsec_blob.align = 8; + + if (!prs_align(&netsec_blob)) { + DEBUG(0,("Could not align netsec blob\n")); + prs_mem_free(&outgoing_packet); + return False; + } + + init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, + sign, nullbytes); + + netsec_encode(&(cli->auth_info), &verf, + prs_data_p(&netsec_blob), + prs_data_size(&netsec_blob)); + + prs_append_prs_data(&outgoing_packet, &netsec_blob); + prs_mem_free(&netsec_blob); + } else { + if(!prs_append_some_prs_data(&outgoing_packet, data, + data_sent, send_size)) { + DEBUG(0,("rpc_api_pipe_req: Failed to append " + "data to outgoing packet.\n")); + prs_mem_free(&outgoing_packet); + return False; + } } /* * Add a trailing auth_verifier if needed. */ if (auth_seal || auth_verify) { - if(!create_auth_hdr(&outgoing_packet, auth_verify)) { + if(!create_ntlmssp_auth_hdr(&outgoing_packet, auth_verify)) { prs_mem_free(&outgoing_packet); return False; } @@ -918,6 +1085,21 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, } } + if (auth_schannel) { + + if (!create_netsec_auth_hdr(&outgoing_packet, + auth_padding)) { + prs_mem_free(&outgoing_packet); + return False; + } + + if (!smb_io_rpc_auth_netsec_chk("", &verf, + &outgoing_packet, 0)) { + prs_mem_free(&outgoing_packet); + return False; + } + } + DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet))); @@ -1191,7 +1373,8 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 Do an rpc bind. ****************************************************************************/ -BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name) +static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name, + BOOL do_netsec) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1220,7 +1403,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name) rpc_call_id = get_rpc_call_id(); /* Marshall the outgoing data. */ - create_rpc_bind_req(&rpc_out, do_auth, rpc_call_id, + create_rpc_bind_req(&rpc_out, do_auth, do_netsec, rpc_call_id, &abstract, &transfer, global_myname(), cli->domain, cli->ntlmssp_cli_flgs); @@ -1310,7 +1493,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) { + if (!rpc_pipe_bind(cli, pipe_idx, global_myname(), False)) { DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n", get_pipe_name_from_index(pipe_idx))); cli_close(cli, cli->nt_pipe_fnum); @@ -1340,6 +1523,106 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) } +/**************************************************************************** + Open a session to the NETLOGON pipe using schannel. + ****************************************************************************/ + +BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, + int sec_chan) +{ + NTSTATUS result; + uint32 neg_flags = 0x000001ff; + int fnum; + + if (lp_client_schannel() != False) + neg_flags |= NETLOGON_NEG_SCHANNEL; + + + if (!cli_nt_session_open(cli, PI_NETLOGON)) { + return False; + } + + if (!secrets_init()) { + DEBUG(3,("Failed to init secrets.tdb\n")); + return False; + } + + result = cli_nt_setup_creds(cli, sec_chan, trust_password, + &neg_flags, 2); + + if (!NT_STATUS_IS_OK(result)) { + cli_nt_session_close(cli); + return False; + } + + if ((lp_client_schannel() == True) && + ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { + + DEBUG(3, ("Server did not offer schannel\n")); + cli_nt_session_close(cli); + return False; + } + + if ((lp_client_schannel() == False) || + ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { + return True; + } + + /* Server offered schannel, so try it. */ + + cli->auth_info.seq_num = 0; + memcpy(cli->auth_info.sess_key, cli->sess_key, + sizeof(cli->auth_info.sess_key)); + + cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum; + + if (cli->capabilities & CAP_NT_SMBS) { + + /* If we open \\PIPE\NETLOGON here, NT4SP6 + gives us an ACCESS_DENIED. Do I have to + understand this? + */ + if ((fnum = cli_nt_create(cli, PIPE_NETLOGON_PLAIN, + DESIRED_ACCESS_PIPE)) == -1) { + DEBUG(0,("cli_nt_create failed to %s machine %s. " + "Error was %s\n", + PIPE_NETLOGON, cli->desthost, + cli_errstr(cli))); + return False; + } + + cli->nt_pipe_fnum = (uint16)fnum; + } else { + if ((fnum = cli_open(cli, PIPE_NETLOGON, + O_CREAT|O_RDWR, DENY_NONE)) == -1) { + DEBUG(0,("cli_open failed on pipe %s to machine %s. " + "Error was %s\n", + PIPE_NETLOGON, cli->desthost, + cli_errstr(cli))); + return False; + } + + cli->nt_pipe_fnum = (uint16)fnum; + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, PIPE_NETLOGON, 0x4300)) { + DEBUG(0,("Pipe hnd state failed. Error was %s\n", + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); + return False; + } + } + + if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) { + DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); + cli_close(cli, cli->nt_pipe_fnum); + return False; + } + + return True; +} + + const char *cli_pipe_get_name(struct cli_state *cli) { return cli->pipe_name; @@ -1352,6 +1635,10 @@ close the session void cli_nt_session_close(struct cli_state *cli) { + if (cli->saved_netlogon_pipe_fnum != 0) { + cli_close(cli, cli->saved_netlogon_pipe_fnum); + cli->saved_netlogon_pipe_fnum = 0; + } cli_close(cli, cli->nt_pipe_fnum); cli->nt_pipe_fnum = 0; } diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index 700ce8cfd6..656082e05a 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -1128,6 +1128,18 @@ BOOL smb_io_rpc_auth_ntlmssp_chk(const char *desc, RPC_AUTH_NTLMSSP_CHK *chk, pr return True; } +/******************************************************************* +creates an RPC_AUTH_NETSEC_NEG structure. +********************************************************************/ +void init_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg, + const char *domain, const char *myname) +{ + neg->unknown1 = 0; + neg->unknown2 = 0x13; + fstrcpy(neg->domain, domain); + fstrcpy(neg->myname, myname); +} + /******************************************************************* Reads or writes an RPC_AUTH_NETSEC_NEG structure. ********************************************************************/ @@ -1148,11 +1160,11 @@ BOOL smb_io_rpc_auth_netsec_neg(const char *desc, RPC_AUTH_NETSEC_NEG *neg, return False; if(!prs_uint32("unknown2", ps, depth, &neg->unknown2)) return False; - if(!prs_string("domain ", ps, depth, neg->domain, - strlen(&ps->data_p[ps->data_offset]), sizeof(neg->domain))) - return False; if(!prs_string("myname ", ps, depth, neg->myname, - strlen(&ps->data_p[ps->data_offset]), sizeof(neg->myname))) + strlen(neg->myname), sizeof(neg->myname))) + return False; + if(!prs_string("domain ", ps, depth, neg->domain, + strlen(neg->domain), sizeof(neg->domain))) return False; return True; diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 1421c4da26..e6ec28beab 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -296,25 +296,6 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, if (argc == 6) sscanf(argv[5], "%i", &auth_level); - /* Authenticate ourselves with the domain controller */ - - if (!secrets_init()) { - fprintf(stderr, "Unable to initialise secrets database\n"); - return result; - } - - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) { - fprintf(stderr, "could not fetch trust account password\n"); - goto done; - } - - result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, auth_level); - - if (!NT_STATUS_IS_OK(result)) { - fprintf(stderr, "Error initialising session creds\n"); - goto done; - } - /* Perform the sam logon */ result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, logon_type); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 6c1d05b3e9..1de181f77c 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -389,11 +389,28 @@ static NTSTATUS do_cmd(struct cli_state *cli, /* Open pipe */ - if (cmd_entry->pipe_idx != -1) - if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { - DEBUG(0, ("Could not initialize pipe\n")); + if (cmd_entry->pipe_idx == PI_NETLOGON) { + uchar trust_password[16]; + + if (!secrets_fetch_trust_account_password(lp_workgroup(), + trust_password, + NULL)) { + return NT_STATUS_UNSUCCESSFUL; + } + + if (!cli_nt_open_netlogon(cli, trust_password, + SEC_CHAN_WKSTA)) { + DEBUG(0, ("Could not initialize NETLOGON pipe\n")); return NT_STATUS_UNSUCCESSFUL; } + } else { + if (cmd_entry->pipe_idx != -1) { + if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { + DEBUG(0, ("Could not initialize pipe\n")); + return NT_STATUS_UNSUCCESSFUL; + } + } + } /* Run command */ diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index e42c8f5637..0b78cd54ce 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -209,19 +209,17 @@ int rpc_samdump(int argc, const char **argv) return 1; } - if (!cli_nt_session_open(cli, PI_NETLOGON)) { - DEBUG(0,("Error connecting to NETLOGON pipe\n")); - goto fail; - } + fstrcpy(cli->domain, lp_workgroup()); - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL)) { - d_printf("Could not retrieve domain trust secret\n"); + if (!secrets_fetch_trust_account_password(lp_workgroup(), + trust_password, + NULL)) { + DEBUG(0,("Could not fetch trust account password\n")); goto fail; } - - result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password, &neg_flags, 2); - if (!NT_STATUS_IS_OK(result)) { - d_printf("Failed to setup BDC creds\n"); + + if (!cli_nt_open_netlogon(cli, trust_password, SEC_CHAN_BDC)) { + DEBUG(0,("Error connecting to NETLOGON pipe\n")); goto fail; } -- cgit From 1f04eb2e2617ac05974c21bdac9ebb4781b5a9d9 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 9 Apr 2003 16:48:59 +0000 Subject: Complete what I've seen (and then some)t of the PAC. I haven't seen the rid+attr arrays for group membership, nor sids or the same kind of arrays for resource domains, so I don't know how that will work. Also, the PAC info type 10 is now decoded, but I don't know what it's for. It has an NTTIME, a 16-bit name length, and a username. According to M$, it's not needed, because they didn't doc it... (This used to be commit 28ab8504cf6c181866106e5cc626a5896283d0a9) --- source3/include/authdata.h | 22 ++++++-- source3/libads/authdata.c | 129 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 141 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/include/authdata.h b/source3/include/authdata.h index 1521185a8f..0798b72bdf 100644 --- a/source3/include/authdata.h +++ b/source3/include/authdata.h @@ -27,6 +27,13 @@ #define PAC_TYPE_LOGON_INFO 1 #define PAC_TYPE_SERVER_CHECKSUM 6 #define PAC_TYPE_PRIVSVR_CHECKSUM 7 +#define PAC_TYPE_UNKNOWN_10 10 + +typedef struct unknown_type_10 { + NTTIME unknown_time; + uint16 len; + uint16 *username; /* might not be null terminated, so not UNISTR */ +} UNKNOWN_TYPE_10; typedef struct pac_signature_data { uint32 type; @@ -38,6 +45,11 @@ typedef struct group_membership { uint32 attrs; } GROUP_MEMBERSHIP; +typedef struct group_membership_array { + uint32 count; + GROUP_MEMBERSHIP *group_membership; +} GROUP_MEMBERSHIP_ARRAY; + typedef struct krb_sid_and_attrs { uint32 sid_ptr; uint32 attrs; @@ -93,7 +105,7 @@ typedef struct pac_logon_info { uint32 ptr_res_group_dom_sid; uint32 res_group_count; - uint32 ptr_res_group_sids; + uint32 ptr_res_groups; UNISTR2 uni_user_name; /* user name unicode string header */ UNISTR2 uni_full_name; /* user's full name unicode string header */ @@ -104,12 +116,11 @@ typedef struct pac_logon_info { UNISTR2 uni_dom_controller; UNISTR2 uni_dom_name; DOM_SID2 dom_sid; - /* group membership array needs to go in here. - I've not seen it on the wire */ + GROUP_MEMBERSHIP_ARRAY groups; KRB_SID_AND_ATTR_ARRAY extra_sids; DOM_SID2 res_group_dom_sid; - /* resource group membership array needs to go in here */ - + GROUP_MEMBERSHIP_ARRAY res_groups; + } PAC_LOGON_INFO; typedef struct pac_info_ctr @@ -119,6 +130,7 @@ typedef struct pac_info_ctr PAC_LOGON_INFO *logon_info; PAC_SIGNATURE_DATA *srv_cksum; PAC_SIGNATURE_DATA *privsrv_cksum; + UNKNOWN_TYPE_10 *type_10; } pac; } PAC_INFO_CTR; diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 3d25aec205..c554a02e90 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -42,6 +42,38 @@ static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) return pac_contents; } +static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10, + prs_struct *ps, int depth) +{ + if (NULL == type_10) + return False; + + prs_debug(ps, depth, desc, "pac_io_unknown_type_10"); + depth++; + + if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth)) + return False; + + if (!prs_uint16("len", ps, depth, &type_10->len)) + return False; + + if (UNMARSHALLING(ps) && type_10->len) { + type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len); + if (!type_10->username) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if (!prs_uint16s(True, "name", ps, depth, type_10->username, + (type_10->len / sizeof(uint16)))) + return False; + + return True; + +} + + static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, prs_struct *ps, int depth) { @@ -129,6 +161,63 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc, } +static BOOL pac_io_group_membership(const char *desc, + GROUP_MEMBERSHIP *membership, + prs_struct *ps, int depth) +{ + if (NULL == membership) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership"); + depth++; + + if (!prs_uint32("rid", ps, depth, &membership->rid)) + return False; + if (!prs_uint32("attrs", ps, depth, &membership->attrs)) + return False; + + return True; +} + + +static BOOL pac_io_group_membership_array(const char *desc, + GROUP_MEMBERSHIP_ARRAY *array, + uint32 num, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == array) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership_array"); + depth++; + + + if (!prs_uint32("count", ps, depth, &array->count)) + return False; + + if (UNMARSHALLING(ps)) { + array->group_membership = (GROUP_MEMBERSHIP *) + prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num); + if (!array->group_membership) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + for (i=0; igroup_membership[i], + ps, depth)) + return False; + + } + + return True; + +} + static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { @@ -253,8 +342,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, return False; if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) return False; - if (!prs_uint32("ptr_res_group_sids", ps, depth, - &info->ptr_res_group_sids)) + if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups)) return False; if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, @@ -276,7 +364,14 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, info->hdr_dir_drive.buffer, ps, depth)) return False; - /* the group membership list will need to be handled here */ + if (info->group_membership_ptr) { + if (!pac_io_group_membership_array("group membership", + &info->groups, + info->group_count, + ps, depth)) + return False; + } + if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, info->hdr_dom_controller.buffer, ps, depth)) @@ -290,14 +385,24 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, return False; - if (info->sid_count && info->ptr_extra_sids) { + if (info->sid_count && info->ptr_extra_sids) if (!pac_io_krb_sid_and_attr_array("extra_sids", &info->extra_sids, info->sid_count, ps, depth)) return False; - } + if (info->ptr_res_group_dom_sid) + if (!smb_io_dom_sid2("res_group_dom_sid", + &info->res_group_dom_sid, ps, depth)) + return False; + + if (info->ptr_res_groups) + if (!pac_io_group_membership_array("res group membership", + &info->res_groups, + info->res_group_count, + ps, depth)) + return False; return True; } @@ -400,6 +505,20 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, return False; break; + case PAC_TYPE_UNKNOWN_10: + DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *) + prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10)); + if (!hdr->ctr->pac.type_10) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10, + ps, depth)) + return False; + break; + default: /* dont' know, so we need to skip it */ DEBUG(3, ("unknown PAC type %d\n", hdr->type)); -- cgit From 525d18a2b0bb04639100adacb359d35da8472dfc Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 9 Apr 2003 17:36:33 +0000 Subject: collaps same repeted task into 2 code paths (This used to be commit bc5d1873da187c83a1a19a7560685ed903d37455) --- source3/modules/vfs_recycle.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index d554f4bfdd..3a23e1a365 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -555,11 +555,10 @@ static int recycle_unlink(connection_struct *conn, const char *file_name) /* see if we need to recreate the original directory structure in the recycle bin */ if (recbin->keep_dir_tree == True) { asprintf(&temp_name, "%s/%s", recbin->repository, path_name); - ALLOC_CHECK(temp_name, done); } else { temp_name = strdup(recbin->repository); - ALLOC_CHECK(temp_name, done); } + ALLOC_CHECK(temp_name, done); exist = recycle_directory_exist(conn, temp_name); if (exist) { -- cgit From 80b4dc47132ce5c4b0212cab8e719f950c9d29f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Apr 2003 22:32:04 +0000 Subject: Ensure we have WinXP-like semantics for checking TIDs and FIDs. Add torture test to ensure this is so. Jeremy. (This used to be commit e07dd4d93d2bf6ed83dd055efd29d11f5cd66a36) --- source3/torture/torture.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'source3') diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 5935c8c06e..0db4630845 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -171,6 +171,22 @@ BOOL torture_open_connection(struct cli_state **c) return True; } +BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid) +{ + uint16 old_vuid = cli->vuid; + fstring old_user_name; + size_t passlen = strlen(password); + BOOL ret; + + fstrcpy(old_user_name, cli->user_name); + cli->vuid = 0; + ret = cli_session_setup(cli, username, password, passlen, password, passlen, workgroup); + *new_vuid = cli->vuid; + cli->vuid = old_vuid; + fstrcpy(cli->user_name, old_user_name); + return ret; +} + BOOL torture_close_connection(struct cli_state *c) { @@ -1935,6 +1951,54 @@ static BOOL run_fdpasstest(int dummy) return True; } +static BOOL run_fdsesstest(int dummy) +{ + struct cli_state *cli; + uint16 new_vuid; + uint16 saved_vuid; + const char *fname = "\\fdsess.tst"; + int fnum1; + pstring buf; + + if (!torture_open_connection(&cli)) + return False; + cli_sockopt(cli, sockops); + + if (!torture_cli_session_setup2(cli, &new_vuid)) + return False; + + printf("starting fdsesstest\n"); + + cli_unlink(cli, fname); + + fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); + if (fnum1 == -1) { + printf("open of %s failed (%s)\n", fname, cli_errstr(cli)); + return False; + } + + if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) { + printf("write failed (%s)\n", cli_errstr(cli)); + return False; + } + + saved_vuid = cli->vuid; + cli->vuid = new_vuid; + + if (cli_read(cli, fnum1, buf, 0, 13) == 13) { + printf("read succeeded! nasty security hole [%s]\n", + buf); + return False; + } + + cli_close(cli, fnum1); + cli_unlink(cli, fname); + + torture_close_connection(cli); + + printf("finished fdsesstest\n"); + return True; +} /* This test checks that @@ -4448,6 +4512,7 @@ static struct { {"TCON2", run_tcon2_test, 0}, {"IOCTL", torture_ioctl_test, 0}, {"CHKPATH", torture_chkpath_test, 0}, + {"FDSESS", run_fdsesstest, 0}, {NULL, NULL, 0}}; -- cgit From 0294da3caa340889c3e252df5e0437dee47508c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Apr 2003 22:34:58 +0000 Subject: Fix from Steve Langasek for non-RPC printing. Jeremy. (This used to be commit 186d53cbc1642ee5dd1daf0277dc08de621eede2) --- source3/smbd/service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 5c87eb0729..146212701e 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -229,7 +229,7 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev) if (dev[0] == '?' || !dev[0]) { if (lp_print_ok(snum)) { - fstrcpy(dev,"LPT1:"); + fstrcpy(dev,"LPT:"); } else if (strequal(lp_fstype(snum), "IPC")) { fstrcpy(dev, "IPC"); } else { @@ -253,7 +253,7 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev) /* Behave as a printer if we are supposed to */ if (lp_print_ok(snum) && (strcmp(dev, "A:") == 0)) { - fstrcpy(dev, "LPT1:"); + fstrcpy(dev, "LPT:"); } return NT_STATUS_OK; -- cgit From dfdb51ca4576c5de6b1d09aaa1e2adb18d115849 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Apr 2003 01:11:21 +0000 Subject: Added using different cnum test. WinXP and Samba now pass - Win2k fails. Jeremy. (This used to be commit bc094789b972ac5ccc7ea3944c7ddb98581cf613) --- source3/torture/torture.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 0db4630845..5ff7c3bb2d 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -1956,9 +1956,12 @@ static BOOL run_fdsesstest(int dummy) struct cli_state *cli; uint16 new_vuid; uint16 saved_vuid; + uint16 new_cnum; + uint16 saved_cnum; const char *fname = "\\fdsess.tst"; int fnum1; pstring buf; + BOOL ret = True; if (!torture_open_connection(&cli)) return False; @@ -1967,6 +1970,12 @@ static BOOL run_fdsesstest(int dummy) if (!torture_cli_session_setup2(cli, &new_vuid)) return False; + saved_cnum = cli->cnum; + if (!cli_send_tconX(cli, share, "?????", "", 1)) + return False; + new_cnum = cli->cnum; + cli->cnum = saved_cnum; + printf("starting fdsesstest\n"); cli_unlink(cli, fname); @@ -1986,18 +1995,29 @@ static BOOL run_fdsesstest(int dummy) cli->vuid = new_vuid; if (cli_read(cli, fnum1, buf, 0, 13) == 13) { - printf("read succeeded! nasty security hole [%s]\n", + printf("read succeeded with different vuid! nasty security hole [%s]\n", buf); - return False; + ret = False; + } + cli->vuid = saved_vuid; + + /* Try with same vuid, different cnum. */ + cli->cnum = new_cnum; + + if (cli_read(cli, fnum1, buf, 0, 13) == 13) { + printf("read succeeded with different cnum![%s]\n", + buf); + ret = False; } + cli->cnum = saved_cnum; cli_close(cli, fnum1); cli_unlink(cli, fname); torture_close_connection(cli); printf("finished fdsesstest\n"); - return True; + return ret; } /* -- cgit From acfddbe0b882931c4afc8020c4968fc67a220007 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 10 Apr 2003 05:16:49 +0000 Subject: Fixes to linker flags for AIX winbind client from Stephen Roylance. (This used to be commit 1cc5b2881c61db7aadd886008fcfb81e351e651a) --- source3/Makefile.in | 3 ++- source3/configure.in | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index cf8791a9a8..99e557b7a7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -19,6 +19,7 @@ CPPFLAGS=@CPPFLAGS@ EXEEXT=@EXEEXT@ LDFLAGS=@LDFLAGS@ LDSHFLAGS=@LDSHFLAGS@ @LDFLAGS@ @CFLAGS@ +WINBIND_NSS_LDSHFLAGS=@WINBIND_NSS_LDSHFLAGS@ @LDFLAGS@ @CFLAGS@ AWK=@AWK@ DYNEXP=@DYNEXP@ PYTHON=@PYTHON@ @@ -954,7 +955,7 @@ bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy nsswitch/@WINBIND_NSS@.@SHLIBEXT@: $(WINBIND_NSS_PICOBJS) @echo "Linking $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_NSS_PICOBJS) \ + @$(SHLD) $(WINBIND_NSS_LDSHFLAGS) -o $@ $(WINBIND_NSS_PICOBJS) \ @WINBIND_NSS_EXTRA_LIBS@ @SONAMEFLAG@`basename $@` nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_OBJ) bin/.dummy diff --git a/source3/configure.in b/source3/configure.in index 2b086d3d3b..c2b7ae2765 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -3222,7 +3222,11 @@ AC_MSG_CHECKING(whether to build winbind) HAVE_WINBIND=yes +# Define the winbind shared library name and any specific linker flags +# it needs to be built with. + WINBIND_NSS=libnss_winbind +WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS case "$host_os" in *linux*) @@ -3244,6 +3248,7 @@ case "$host_os" in ;; *aix*) WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_aix.o" + WINBIND_NSS_LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-ewb_aix_init" ;; *) HAVE_WINBIND=no @@ -3252,6 +3257,7 @@ case "$host_os" in esac AC_SUBST(WINBIND_NSS) +AC_SUBST(WINBIND_NSS_LDSHFLAGS) AC_SUBST(WINBIND_NSS_EXTRA_OBJS) AC_SUBST(WINBIND_NSS_EXTRA_LIBS) -- cgit From ac65d890703c85fe69e2c577061087b8da2a4a93 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Apr 2003 18:43:00 +0000 Subject: Ensure we're not filtering our essential delete messages. Added jobid debug when unpacking message. Jeremy. (This used to be commit 8bab6e32069e1636a52efa31ca55b49f1b3fa768) --- source3/printing/notify.c | 32 +++++++++++++++++++++----------- source3/rpc_server/srv_spoolss_nt.c | 4 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/printing/notify.c b/source3/printing/notify.c index 641f951bdd..428eb54ce4 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -24,6 +24,8 @@ static TALLOC_CTX *send_ctx; +static unsigned int num_messages; + static struct notify_queue { struct notify_queue *next, *prev; struct spoolss_notify_msg *msg; @@ -128,6 +130,7 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned if (!flatten_message(pq)) { DEBUG(0,("print_notify_send_messages: Out of memory\n")); talloc_destroy_pool(send_ctx); + num_messages = 0; return; } offset += (pq->buflen + 4); @@ -140,6 +143,7 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned if (!buf) { DEBUG(0,("print_notify_send_messages: Out of memory\n")); talloc_destroy_pool(send_ctx); + num_messages = 0; return; } @@ -190,6 +194,7 @@ void print_notify_send_messages(unsigned int timeout) print_notify_send_messages_to_printer(notify_queue_head->msg->printer, timeout); talloc_destroy_pool(send_ctx); + num_messages = 0; } /********************************************************************** @@ -225,23 +230,27 @@ static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg) struct notify_queue *pnqueue, *tmp_ptr; /* - * Ensure we only have one message unique to each name/type/field/id/flags - * tuple. There is no point in sending multiple messages that match + * Ensure we only have one job total_bytes and job total_pages for + * each job. There is no point in sending multiple messages that match * as they will just cause flickering updates in the client. */ - for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) { - if (tmp_ptr->msg->type == msg->type && - tmp_ptr->msg->field == msg->field && - tmp_ptr->msg->id == msg->id && - tmp_ptr->msg->flags == msg->flags && - strequal(tmp_ptr->msg->printer, msg->printer)) { + if ((num_messages < 100) && (msg->type == JOB_NOTIFY_TYPE) && + (msg->field == JOB_NOTIFY_TOTAL_BYTES || msg->field == JOB_NOTIFY_TOTAL_PAGES)) { + + for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) { + if (tmp_ptr->msg->type == msg->type && + tmp_ptr->msg->field == msg->field && + tmp_ptr->msg->id == msg->id && + tmp_ptr->msg->flags == msg->flags && + strequal(tmp_ptr->msg->printer, msg->printer)) { - DEBUG(5, ("send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for printer %s \ + DEBUG(5, ("send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for printer %s \ in notify_queue\n", msg->type, msg->field, msg->printer)); - tmp_ptr->msg = msg; - return; + tmp_ptr->msg = msg; + return; + } } } @@ -274,6 +283,7 @@ to notify_queue_head\n", msg->type, msg->field, msg->printer)); */ DLIST_ADD_END(notify_queue_head, pnqueue, tmp_ptr); + num_messages++; } static void send_notify_field_values(const char *printer_name, uint32 type, diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 9f943f036a..c4ae894296 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -1053,8 +1053,8 @@ static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi tdb_unpack((char *)buf + offset, len - offset, "B", &msg->len, &msg->notify.data); - DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message, type %d, field 0x%02x, flags 0x%04x\n", - msg->type, msg->field, msg->flags)); + DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n", + msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags)); tv->tv_sec = tv_sec; tv->tv_usec = tv_usec; -- cgit From ba9f9afe8b6ca8c008ac8f97c43d896e1cbc4b91 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Apr 2003 19:08:42 +0000 Subject: Fix from Andrew Esh to ensure tdb_pack can't segfault. Also stop it leaking memory like a sieve ! Jeremy. (This used to be commit 11b914ed84c4dbd31726969b3b924f686f938510) --- source3/tdb/tdbutil.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index b153d442bd..69b282cda0 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -42,7 +42,7 @@ static void gotalarm_sig(void) static TDB_DATA make_tdb_data(const char *dptr, size_t dsize) { TDB_DATA ret; - ret.dptr = smb_xstrdup(dptr); + ret.dptr = dptr; ret.dsize = dsize; return ret; } @@ -406,47 +406,47 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) case 'b': /* unsigned 8-bit integer */ len = 1; bt = (uint8)va_arg(ap, int); - if (bufsize >= len) + if (bufsize && bufsize >= len) SSVAL(buf, 0, bt); break; case 'w': /* unsigned 16-bit integer */ len = 2; w = (uint16)va_arg(ap, int); - if (bufsize >= len) + if (bufsize && bufsize >= len) SSVAL(buf, 0, w); break; case 'd': /* signed 32-bit integer (standard int in most systems) */ len = 4; d = va_arg(ap, uint32); - if (bufsize >= len) + if (bufsize && bufsize >= len) SIVAL(buf, 0, d); break; case 'p': /* pointer */ len = 4; p = va_arg(ap, void *); d = p?1:0; - if (bufsize >= len) + if (bufsize && bufsize >= len) SIVAL(buf, 0, d); break; case 'P': /* null-terminated string */ s = va_arg(ap,char *); w = strlen(s); len = w + 1; - if (bufsize >= len) + if (bufsize && bufsize >= len) memcpy(buf, s, len); break; case 'f': /* null-terminated string */ s = va_arg(ap,char *); w = strlen(s); len = w + 1; - if (bufsize >= len) + if (bufsize && bufsize >= len) memcpy(buf, s, len); break; case 'B': /* fixed-length string */ i = va_arg(ap, int); s = va_arg(ap, char *); len = 4+i; - if (bufsize >= len) { + if (bufsize && bufsize >= len) { SIVAL(buf, 0, i); memcpy(buf+4, s, i); } @@ -459,7 +459,10 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) } buf += len; - bufsize -= len; + if (bufsize) + bufsize -= len; + if (bufsize < 0) + bufsize = 0; } va_end(ap); -- cgit From b9b544ebe808881f51025265c0246928544309f3 Mon Sep 17 00:00:00 2001 From: Shirish Kalele Date: Thu, 10 Apr 2003 19:55:30 +0000 Subject: Handle deep referrals: check whether each component in the requested path of a referral request is a dfs link, and redirect. Thanks to John Janosik for the patch. (This used to be commit b3bd4818571c55b3f0cd6316b0aa6b1e4bb4bb6a) --- source3/msdfs/msdfs.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index bf3b3cc213..fa6617cb52 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -215,6 +215,7 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, char *p; fstring reqpath; + pstring consumedbuf; if (!dp || !conn) { DEBUG(1,("resolve_dfs_path: NULL dfs_path* or NULL connection_struct*!\n")); @@ -247,10 +248,13 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, } } - /* also redirect if the parent directory is a dfs link */ + pstrcpy(consumedbuf, dfspath); + trim_string(consumedbuf, NULL, "\\"); + + /* redirect if any component in the path is a link */ fstrcpy(reqpath, dp->reqpath); p = strrchr(reqpath, '/'); - if (p) { + while (p) { *p = '\0'; fstrcpy(localpath, conn->connectpath); fstrcat(localpath, "/"); @@ -265,18 +269,16 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, */ if (consumedcntp) { char *q; - pstring buf; - pstrcpy(buf, dfspath); - trim_string(buf, NULL, "\\"); - q = strrchr(buf, '\\'); + q = strrchr(consumedbuf, '\\'); if (q) *q = '\0'; - *consumedcntp = strlen(buf); + *consumedcntp = strlen(consumedbuf); DEBUG(10, ("resolve_dfs_path: Path consumed: %d\n", *consumedcntp)); } return True; } + p = strrchr(reqpath, '/'); } return False; @@ -629,8 +631,7 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) /* Trim pathname sent by client so it begins with only one backslash. Two backslashes confuse some dfs clients */ - while (strlen(pathnamep) > 1 && pathnamep[0] == '\\' - && pathnamep[1] == '\\') + while (pathnamep[0] == '\\' && pathnamep[1] == '\\') pathnamep++; pstrcpy(buf, pathnamep); -- cgit From 065561932c660be13f80fefa2a310a51b0c07f9c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 11 Apr 2003 04:09:14 +0000 Subject: A new RPC pipe! The \pipe\echo named pipe is for testing large RPC requests and responses and is only compiled in when --enable-developer is passed to configure. It includes server and client side code for generating and responding to functions on this pipe. The functions are: - AddOne: add one to the uint32 argument and return ig - EchoData: echo back a variable sized char array to the caller - SourceData: request a variable sized char array - SinkData: send a variable sized char array and throw it away There's a win32 implementation of the client and server in the junkcode CVS repository in the rpcecho-win32 subdirectory. (This used to be commit 4ccd34ef836eba05f81dc2da73fd7cfaac201798) --- source3/Makefile.in | 15 +++- source3/configure.in | 5 ++ source3/include/ntdomain.h | 2 + source3/include/rpc_echo.h | 74 ++++++++++++++++ source3/include/smb.h | 4 +- source3/lib/util.c | 44 --------- source3/rpc_client/cli_echo.c | 187 +++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_echo.c | 166 ++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_rpc.c | 10 +++ source3/rpc_server/srv_echo.c | 137 ++++++++++++++++++++++++++++ source3/rpc_server/srv_echo_nt.c | 78 ++++++++++++++++ source3/rpcclient/cmd_echo.c | 157 ++++++++++++++++++++++++++++++++ source3/rpcclient/rpcclient.c | 7 +- source3/smbd/nttrans.c | 1 + 14 files changed, 837 insertions(+), 50 deletions(-) create mode 100644 source3/include/rpc_echo.h create mode 100644 source3/rpc_client/cli_echo.c create mode 100644 source3/rpc_parse/parse_echo.c create mode 100644 source3/rpc_server/srv_echo.c create mode 100644 source3/rpc_server/srv_echo_nt.c create mode 100644 source3/rpcclient/cmd_echo.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 99e557b7a7..641294790d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -226,7 +226,7 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ rpc_client/cli_wkssvc.o rpc_client/cli_dfs.o \ rpc_client/cli_reg.o rpc_client/cli_pipe.o \ rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \ - rpc_client/cli_ds.o libsmb/namequery_dc.o + rpc_client/cli_ds.o rpc_client/cli_echo.o libsmb/namequery_dc.o LIBMSRPC_SERVER_OBJ = libsmb/trusts_util.o @@ -253,6 +253,8 @@ RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o rpc_server/srv_util.o \ rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o +RPC_ECHO_OBJ = rpc_server/srv_echo.o rpc_server/srv_echo_nt.o + RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ) # this includes only the low level parse code, not stuff @@ -265,6 +267,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \ rpc_parse/parse_samr.o rpc_parse/parse_srv.o \ rpc_parse/parse_wks.o rpc_parse/parse_ds.o \ rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \ + rpc_parse/parse_echo.o \ $(REGOBJS_OBJ) @@ -424,7 +427,8 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \ rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \ rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \ - rpcclient/display_sec.o rpcclient/cmd_ds.o + rpcclient/display_sec.o rpcclient/cmd_ds.o \ + rpcclient/cmd_echo.o RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ @@ -557,7 +561,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \ $(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \ $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \ - $(IDMAP_OBJ) + $(IDMAP_OBJ) $(RPC_ECHO_OBJ) NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \ $(LIB_OBJ) $(NSSWINS_OBJ) @@ -943,6 +947,11 @@ bin/librpc_netdfs.@SHLIBEXT@: $(RPC_DFS_OBJ) @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_DFS_OBJ) -lc \ @SONAMEFLAG@`basename $@` +bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ) + @echo "Linking $@" + @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_ECHO_OBJ) -lc \ + @SONAMEFLAG@`basename $@` + nsswitch/libnss_wins.@SHLIBEXT@: $(NSS_OBJ) @echo "Linking $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(NSS_OBJ) -lc \ diff --git a/source3/configure.in b/source3/configure.in index c2b7ae2765..ce53358d09 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -247,6 +247,10 @@ dnl Add modules that have to be built by default here dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_unix rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin idmap_winbind" +if test "x$enable_developer" = xyes; then + default_static_modules="$default_static_modules rpc_echo" +fi + dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_fake_perms vfs_netatalk" @@ -3460,6 +3464,7 @@ SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC) SMB_MODULE(rpc_srv, \$(RPC_SVC_OBJ), "bin/librpc_srvsvc.$SHLIBEXT", RPC) SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC) SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC) +SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC) SMB_SUBSYSTEM(RPC) SMB_MODULE(charset_weird, modules/developer.o, "bin/developer.$SHLIBEXT", CHARSET) diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 9216640c03..b6ab4fd0c5 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -385,4 +385,6 @@ struct acct_info #include "rpc_spoolss.h" #include "rpc_dfs.h" #include "rpc_ds.h" +#include "rpc_echo.h" + #endif /* _NT_DOMAIN_H */ diff --git a/source3/include/rpc_echo.h b/source3/include/rpc_echo.h new file mode 100644 index 0000000000..8fa389cf56 --- /dev/null +++ b/source3/include/rpc_echo.h @@ -0,0 +1,74 @@ +/* + Unix SMB/CIFS implementation. + + Samba rpcecho definitions. + + Copyright (C) Tim Potter 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _RPC_ECHO_H +#define _RPC_ECHO_H + +#define ECHO_ADD_ONE 0x00 +#define ECHO_DATA 0x01 +#define ECHO_SINK_DATA 0x02 +#define ECHO_SOURCE_DATA 0x03 + +typedef struct echo_q_add_one +{ + uint32 request; +} ECHO_Q_ADD_ONE; + +typedef struct echo_r_add_one +{ + uint32 response; +} ECHO_R_ADD_ONE; + +typedef struct echo_q_echo_data +{ + uint32 size; + char *data; +} ECHO_Q_ECHO_DATA; + +typedef struct echo_r_echo_data +{ + uint32 size; + char *data; +} ECHO_R_ECHO_DATA; + +typedef struct echo_q_source_data +{ + uint32 size; +} ECHO_Q_SOURCE_DATA; + +typedef struct echo_r_source_data +{ + uint32 size; + char *data; +} ECHO_R_SOURCE_DATA; + +typedef struct echo_q_sink_data +{ + uint32 size; + char *data; +} ECHO_Q_SINK_DATA; + +typedef struct echo_r_sink_data +{ +} ECHO_R_SINK_DATA; + +#endif diff --git a/source3/include/smb.h b/source3/include/smb.h index 78690cd524..02b5b9435e 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -187,6 +187,7 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN]; #define PIPE_LSARPC "\\PIPE\\lsarpc" #define PIPE_SPOOLSS "\\PIPE\\spoolss" #define PIPE_NETDFS "\\PIPE\\netdfs" +#define PIPE_ECHO "\\PIPE\\rpcecho" #define PIPE_NETLOGON_PLAIN "\\NETLOGON" @@ -199,7 +200,8 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN]; #define PI_WINREG 6 #define PI_SPOOLSS 7 #define PI_NETDFS 8 -#define PI_MAX_PIPES 9 +#define PI_ECHO 9 +#define PI_MAX_PIPES 10 /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */ typedef struct nttime_info diff --git a/source3/lib/util.c b/source3/lib/util.c index 3ecfc92552..ddc20e492c 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1840,50 +1840,6 @@ enum remote_arch_types get_remote_arch(void) return ra_type; } - -void out_ascii(FILE *f, unsigned char *buf,int len) -{ - int i; - for (i=0;i(per_line/2)) fprintf(f, " "); - while (n--) { - fprintf(f, " "); - } - n = MIN(per_line/2,i%per_line); - out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " "); - n = (i%per_line) - n; - if (n>0) out_ascii(f,&buf[i-n],n); - fprintf(f, "\n"); - } -} - void print_asc(int level, const unsigned char *buf,int len) { int i; diff --git a/source3/rpc_client/cli_echo.c b/source3/rpc_client/cli_echo.c new file mode 100644 index 0000000000..03a4ab36ee --- /dev/null +++ b/source3/rpc_client/cli_echo.c @@ -0,0 +1,187 @@ +/* + Unix SMB/CIFS implementation. + + RPC pipe client + + Copyright (C) Tim Potter 2003 + + 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" + +NTSTATUS cli_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 request, uint32 *response) +{ + prs_struct qbuf, rbuf; + ECHO_Q_ADD_ONE q; + ECHO_R_ADD_ONE r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_add_one(&q, request); + + if (!echo_io_q_add_one("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_ADD_ONE, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!echo_io_r_add_one("", &r, &rbuf, 0)) + goto done; + + if (response) + *response = r.response; + + result = True; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 size, char *in_data, char **out_data) +{ + prs_struct qbuf, rbuf; + ECHO_Q_ECHO_DATA q; + ECHO_R_ECHO_DATA r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_echo_data(&q, size, in_data); + + if (!echo_io_q_echo_data("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_DATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!echo_io_r_echo_data("", &r, &rbuf, 0)) + goto done; + + result = True; + + if (out_data) { + *out_data = talloc(mem_ctx, size); + memcpy(*out_data, r.data, size); + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS cli_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 size, char *in_data) +{ + prs_struct qbuf, rbuf; + ECHO_Q_SINK_DATA q; + ECHO_R_SINK_DATA r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_sink_data(&q, size, in_data); + + if (!echo_io_q_sink_data("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_SINK_DATA, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!echo_io_r_sink_data("", &r, &rbuf, 0)) { + goto done; + } + + result = True; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS cli_echo_source_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 size, char **out_data) +{ + prs_struct qbuf, rbuf; + ECHO_Q_SOURCE_DATA q; + ECHO_R_SOURCE_DATA r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_source_data(&q, size); + + if (!echo_io_q_source_data("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_SOURCE_DATA, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!echo_io_r_source_data("", &r, &rbuf, 0)) { + goto done; + } + + result = True; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} diff --git a/source3/rpc_parse/parse_echo.c b/source3/rpc_parse/parse_echo.c new file mode 100644 index 0000000000..67f9ad772e --- /dev/null +++ b/source3/rpc_parse/parse_echo.c @@ -0,0 +1,166 @@ +/* + * Unix SMB/CIFS implementation. + * + * RPC Pipe client / server routines + * + * Copyright (C) Tim Potter 2003 + * + * 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" +#include "nterr.h" +#include "rpc_parse.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + +void init_echo_q_add_one(ECHO_Q_ADD_ONE *q_d, uint32 request) +{ + q_d->request = request; +} + +BOOL echo_io_q_add_one(const char *desc, ECHO_Q_ADD_ONE *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("request", ps, 0, &q_d->request)) + return False; + + return True; +} + +BOOL echo_io_r_add_one(const char *desc, ECHO_R_ADD_ONE *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("response", ps, 0, &q_d->response)) + return False; + + return True; +} + + +void init_echo_q_echo_data(ECHO_Q_ECHO_DATA *q_d, uint32 size, char *data) +{ + q_d->size = size; + q_d->data = data; +} + +BOOL echo_io_q_echo_data(const char *desc, ECHO_Q_ECHO_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} + +BOOL echo_io_r_echo_data(const char *desc, ECHO_R_ECHO_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, 0, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} + +void init_echo_q_sink_data(ECHO_Q_SINK_DATA *q_d, uint32 size, char *data) +{ + q_d->size = size; + q_d->data = data; +} + +BOOL echo_io_q_sink_data(const char *desc, ECHO_Q_SINK_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} + +BOOL echo_io_r_sink_data(const char *desc, ECHO_R_SINK_DATA *q_d, + prs_struct *ps, int depth) +{ + return True; +} + +void init_echo_q_source_data(ECHO_Q_SOURCE_DATA *q_d, uint32 size) +{ + q_d->size = size; +} + +BOOL echo_io_q_source_data(const char *desc, ECHO_Q_SOURCE_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + return True; +} + +BOOL echo_io_r_source_data(const char *desc, ECHO_R_SOURCE_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, 0, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index 656082e05a..30909c6910 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -138,6 +138,15 @@ interface/version dce/rpc pipe identification }, 0x03 \ } +#define SYNT_ECHO_V1 \ +{ \ + { \ + 0x60a15ec5, 0x4de8, 0x11d7, \ + { 0xa6, 0x37, 0x00, 0x50, \ + 0x56, 0xa2, 0x01, 0x82 } \ + }, 0x01 \ +} + /* * IMPORTANT!! If you update this structure, make sure to * update the index #defines in smb.h. @@ -155,6 +164,7 @@ const struct pipe_id_info pipe_names [] = { PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 }, { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 }, { PIPE_NETDFS , SYNT_NETDFS_V3 , PIPE_NETDFS , TRANS_SYNT_V2 }, + { PIPE_ECHO , SYNT_ECHO_V1 , PIPE_ECHO , TRANS_SYNT_V2 }, { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 } }; diff --git a/source3/rpc_server/srv_echo.c b/source3/rpc_server/srv_echo.c new file mode 100644 index 0000000000..dcd8dd0c53 --- /dev/null +++ b/source3/rpc_server/srv_echo.c @@ -0,0 +1,137 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines for rpcecho + * Copyright (C) Tim Potter 2003. + * + * 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 is the interface to the rpcecho pipe. */ + +#include "includes.h" +#include "nterr.h" + +#ifdef DEVELOPER + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +static BOOL api_add_one(pipes_struct *p) +{ + ECHO_Q_ADD_ONE q_u; + ECHO_R_ADD_ONE r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_add_one("", &q_u, data, 0)) + return False; + + _echo_add_one(p, &q_u, &r_u); + + if(!echo_io_r_add_one("", &r_u, rdata, 0)) + return False; + + return True; +} + +static BOOL api_echo_data(pipes_struct *p) +{ + ECHO_Q_ECHO_DATA q_u; + ECHO_R_ECHO_DATA r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_echo_data("", &q_u, data, 0)) + return False; + + _echo_data(p, &q_u, &r_u); + + if(!echo_io_r_echo_data("", &r_u, rdata, 0)) + return False; + + return True; +} + +static BOOL api_source_data(pipes_struct *p) +{ + ECHO_Q_SOURCE_DATA q_u; + ECHO_R_SOURCE_DATA r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_source_data("", &q_u, data, 0)) + return False; + + _source_data(p, &q_u, &r_u); + + if(!echo_io_r_source_data("", &r_u, rdata, 0)) + return False; + + return True; +} + +static BOOL api_sink_data(pipes_struct *p) +{ + ECHO_Q_SINK_DATA q_u; + ECHO_R_SINK_DATA r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_sink_data("", &q_u, data, 0)) + return False; + + _sink_data(p, &q_u, &r_u); + + if(!echo_io_r_sink_data("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* +\pipe\rpcecho commands +********************************************************************/ + +int rpc_echo_init(void) +{ + struct api_struct api_echo_cmds[] = { + {"ADD_ONE", ECHO_ADD_ONE, api_add_one }, + {"ECHO_DATA", ECHO_DATA, api_echo_data }, + {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data }, + {"SINK_DATA", ECHO_SINK_DATA, api_sink_data }, + }; + + return rpc_pipe_register_commands( + "rpcecho", "rpcecho", api_echo_cmds, + sizeof(api_echo_cmds) / sizeof(struct api_struct)); +} + +#endif /* DEVELOPER */ diff --git a/source3/rpc_server/srv_echo_nt.c b/source3/rpc_server/srv_echo_nt.c new file mode 100644 index 0000000000..ddb76b3a21 --- /dev/null +++ b/source3/rpc_server/srv_echo_nt.c @@ -0,0 +1,78 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines for rpcecho + * Copyright (C) Tim Potter 2003. + * + * 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 is the interface to the rpcecho pipe. */ + +#include "includes.h" +#include "nterr.h" + +#ifdef DEVELOPER + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +/* Add one to the input and return it */ + +void _echo_add_one(pipes_struct *p, ECHO_Q_ADD_ONE *q_u, ECHO_R_ADD_ONE *r_u) +{ + DEBUG(10, ("_echo_add_one\n")); + + r_u->response = q_u->request + 1; +} + +/* Echo back an array of data */ + +void _echo_data(pipes_struct *p, ECHO_Q_ECHO_DATA *q_u, + ECHO_R_ECHO_DATA *r_u) +{ + DEBUG(10, ("_echo_data\n")); + + r_u->data = talloc(p->mem_ctx, q_u->size); + r_u->size = q_u->size; + memcpy(r_u->data, q_u->data, q_u->size); +} + +/* Sink an array of data */ + +void _sink_data(pipes_struct *p, ECHO_Q_SINK_DATA *q_u, + ECHO_R_SINK_DATA *r_u) +{ + DEBUG(10, ("_sink_data\n")); + + /* My that was some yummy data! */ +} + +/* Source an array of data */ + +void _source_data(pipes_struct *p, ECHO_Q_SOURCE_DATA *q_u, + ECHO_R_SOURCE_DATA *r_u) +{ + uint32 i; + + DEBUG(10, ("_source_data\n")); + + r_u->data = talloc(p->mem_ctx, q_u->size); + r_u->size = q_u->size; + + for (i = 0; i < r_u->size; i++) + r_u->data[i] = i & 0xff; +} + +#endif /* DEVELOPER */ diff --git a/source3/rpcclient/cmd_echo.c b/source3/rpcclient/cmd_echo.c new file mode 100644 index 0000000000..79ba744a55 --- /dev/null +++ b/source3/rpcclient/cmd_echo.c @@ -0,0 +1,157 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Tim Potter 2003 + + 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" +#include "rpcclient.h" + +static NTSTATUS cmd_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32 request = 1, response; + NTSTATUS result; + + if (argc > 2) { + printf("Usage: %s [num]\n", argv[0]); + return NT_STATUS_OK; + } + + if (argc == 2) + request = atoi(argv[1]); + + result = cli_echo_add_one(cli, mem_ctx, request, &response); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + printf("%d + 1 = %d\n", request, response); + +done: + return result; +} + +static NTSTATUS cmd_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32 size, i; + NTSTATUS result; + char *in_data = NULL, *out_data = NULL; + + if (argc != 2) { + printf("Usage: %s num\n", argv[0]); + return NT_STATUS_OK; + } + + size = atoi(argv[1]); + in_data = malloc(size); + + for (i = 0; i < size; i++) + in_data[i] = i & 0xff; + + result = cli_echo_data(cli, mem_ctx, size, in_data, &out_data); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + for (i = 0; i < size; i++) { + if (in_data[i] != out_data[i]) { + printf("mismatch at offset %d, %d != %d\n", + i, in_data[i], out_data[i]); + } + } + +done: + SAFE_FREE(in_data); + + return result; +} + +static NTSTATUS cmd_echo_source_data(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + uint32 size, i; + NTSTATUS result; + char *out_data = NULL; + + if (argc != 2) { + printf("Usage: %s num\n", argv[0]); + return NT_STATUS_OK; + } + + size = atoi(argv[1]); + + result = cli_echo_source_data(cli, mem_ctx, size, &out_data); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + for (i = 0; i < size; i++) { + if (out_data && out_data[i] != (i & 0xff)) { + printf("mismatch at offset %d, %d != %d\n", + i, out_data[i], i & 0xff); + } + } + +done: + return result; +} + +static NTSTATUS cmd_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32 size, i; + NTSTATUS result; + char *in_data = NULL; + + if (argc != 2) { + printf("Usage: %s num\n", argv[0]); + return NT_STATUS_OK; + } + + size = atoi(argv[1]); + in_data = malloc(size); + + for (i = 0; i < size; i++) + in_data[i] = i & 0xff; + + result = cli_echo_sink_data(cli, mem_ctx, size, in_data); + + if (!NT_STATUS_IS_OK(result)) + goto done; + +done: + SAFE_FREE(in_data); + + return result; +} + +/* List of commands exported by this module */ + +struct cmd_set echo_commands[] = { + + { "ECHO" }, + + { "echoaddone", RPC_RTYPE_NTSTATUS, cmd_echo_add_one, NULL, PI_ECHO, "Add one to a number", "" }, + { "echodata", RPC_RTYPE_NTSTATUS, cmd_echo_data, NULL, PI_ECHO, "Echo data", "" }, + { "sinkdata", RPC_RTYPE_NTSTATUS, cmd_echo_sink_data, NULL, PI_ECHO, "Sink data", "" }, + { "sourcedata", RPC_RTYPE_NTSTATUS, cmd_echo_source_data, NULL, PI_ECHO, "Source data", "" }, + { NULL } +}; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 1de181f77c..efc883ff9f 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -336,6 +336,7 @@ extern struct cmd_set srvsvc_commands[]; extern struct cmd_set dfs_commands[]; extern struct cmd_set reg_commands[]; extern struct cmd_set ds_commands[]; +extern struct cmd_set echo_commands[]; static struct cmd_set *rpcclient_command_list[] = { rpcclient_commands, @@ -347,6 +348,7 @@ static struct cmd_set *rpcclient_command_list[] = { srvsvc_commands, dfs_commands, reg_commands, + echo_commands, NULL }; @@ -400,13 +402,14 @@ static NTSTATUS do_cmd(struct cli_state *cli, if (!cli_nt_open_netlogon(cli, trust_password, SEC_CHAN_WKSTA)) { - DEBUG(0, ("Could not initialize NETLOGON pipe\n")); + DEBUG(0, ("Could not initialise NETLOGON pipe\n")); return NT_STATUS_UNSUCCESSFUL; } } else { if (cmd_entry->pipe_idx != -1) { if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { - DEBUG(0, ("Could not initialize pipe\n")); + DEBUG(0, ("Could not initialise %s\n", + get_pipe_name_from_index(cmd_entry->pipe_idx))); return NT_STATUS_UNSUCCESSFUL; } } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 6d9c649045..9f7fabb75e 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -40,6 +40,7 @@ static const char *known_nt_pipes[] = { "\\winreg", "\\spoolss", "\\netdfs", + "\\rpcecho", NULL }; -- cgit From 1da829be47a8b291924acc9f2346950744d690ab Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 14:29:19 +0000 Subject: workaround streams leak on SCO openserver 5.0.x (This used to be commit 31eaf11d2e9c38e0f479b41c00e0db92987ae6d0) --- source3/lib/util_sock.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 42527e8fd0..5460bf57b8 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -95,11 +95,15 @@ static void print_socket_options(int s) int value, vlen = 4; const smb_socket_option *p = &socket_options[0]; + /* wrapped in if statement to prevent streams leak in SCO Openserver 5.0 */ + /* reported on samba-technical --jerry */ + if ( DEBUGLEVEL >= 5 ) { for (; p->name != NULL; p++) { if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) { DEBUG(5,("Could not test socket option %s.\n", p->name)); } else { DEBUG(5,("socket option %s = %d\n",p->name,value)); + } } } } -- cgit From 5db951a7d67d3895a41f2a687b313b9b338c0db4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Apr 2003 16:32:39 +0000 Subject: Set the default schannel params to False until we know more. Volker (This used to be commit e99a40a711fad336305bc06beb62ba5668d0ed78) --- source3/param/loadparm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 6a4f15bd6e..1b85ebe152 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -1356,8 +1356,8 @@ static void init_globals(void) Globals.paranoid_server_security = True; Globals.bEncryptPasswords = True; Globals.bUpdateEncrypt = False; - Globals.clientSchannel = Auto; - Globals.serverSchannel = Auto; + Globals.clientSchannel = False; + Globals.serverSchannel = False; Globals.bReadRaw = True; Globals.bWriteRaw = True; Globals.bReadPrediction = False; -- cgit From 70231290eac4e3d9c034daaf44fb64947d9f1bee Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 20:32:54 +0000 Subject: simple fix to hopefully speed up srv_spoolss_replyopenprinter(). Use the client address from the pipe->conn->client_address instead of trying to resolve the name in the _spoolss_rffpcn() request. Should make us more robust as well when the clients are not registered in DNS or WINS. (This used to be commit 78b2c1be7d9923716841627044c4e1578a5b9546) --- source3/rpc_server/srv_spoolss_nt.c | 58 +++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 22 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index c4ae894296..424d7909d1 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -2507,34 +2507,43 @@ done: Connect to the client machine. **********************************************************/ -static BOOL spoolss_connect_to_client(struct cli_state *the_cli, const char *remote_machine) +static BOOL spoolss_connect_to_client(struct cli_state *the_cli, + struct in_addr *client_ip, const char *remote_machine) { ZERO_STRUCTP(the_cli); + if(cli_initialise(the_cli) == NULL) { - DEBUG(0,("connect_to_client: unable to initialize client connection.\n")); + DEBUG(0,("spoolss_connect_to_client: unable to initialize client connection.\n")); return False; } + + if ( is_zero_ip(*client_ip) ) { + if(!resolve_name( remote_machine, &the_cli->dest_ip, 0x20)) { + DEBUG(0,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine)); + cli_shutdown(the_cli); + return False; + } - if(!resolve_name( remote_machine, &the_cli->dest_ip, 0x20)) { - DEBUG(0,("connect_to_client: Can't resolve address for %s\n", remote_machine)); - cli_shutdown(the_cli); - return False; + if (ismyip(the_cli->dest_ip)) { + DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine)); + cli_shutdown(the_cli); + return False; + } } - - if (ismyip(the_cli->dest_ip)) { - DEBUG(0,("connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine)); - cli_shutdown(the_cli); - return False; + else { + the_cli->dest_ip.s_addr = client_ip->s_addr; + DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n", + inet_ntoa(*client_ip) )); } if (!cli_connect(the_cli, remote_machine, &the_cli->dest_ip)) { - DEBUG(0,("connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); + DEBUG(0,("spoolss_connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); cli_shutdown(the_cli); return False; } if (!attempt_netbios_session_request(the_cli, global_myname(), remote_machine, &the_cli->dest_ip)) { - DEBUG(0,("connect_to_client: machine %s rejected the NetBIOS session request.\n", + DEBUG(0,("spoolss_connect_to_client: machine %s rejected the NetBIOS session request.\n", remote_machine)); cli_shutdown(the_cli); return False; @@ -2543,13 +2552,13 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli, const char *rem the_cli->protocol = PROTOCOL_NT1; if (!cli_negprot(the_cli)) { - DEBUG(0,("connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); + DEBUG(0,("spoolss_connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); cli_shutdown(the_cli); return False; } if (the_cli->protocol != PROTOCOL_NT1) { - DEBUG(0,("connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine)); + DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine)); cli_shutdown(the_cli); return False; } @@ -2559,19 +2568,19 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli, const char *rem */ if (!cli_session_setup(the_cli, "", "", 0, "", 0, "")) { - DEBUG(0,("connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); + DEBUG(0,("spoolss_connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); cli_shutdown(the_cli); return False; } if (!(the_cli->sec_mode & 1)) { - DEBUG(0,("connect_to_client: machine %s isn't in user level security mode\n", remote_machine)); + DEBUG(0,("spoolss_connect_to_client: machine %s isn't in user level security mode\n", remote_machine)); cli_shutdown(the_cli); return False; } if (!cli_send_tconX(the_cli, "IPC$", "IPC", "", 1)) { - DEBUG(0,("connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); + DEBUG(0,("spoolss_connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); cli_shutdown(the_cli); return False; } @@ -2582,7 +2591,7 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli, const char *rem */ if(cli_nt_session_open(the_cli, PI_SPOOLSS) == False) { - DEBUG(0,("connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli))); + DEBUG(0,("spoolss_connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli))); cli_nt_session_close(the_cli); cli_ulogoff(the_cli); cli_shutdown(the_cli); @@ -2596,7 +2605,9 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli, const char *rem Connect to the client. ****************************************************************************/ -static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle) +static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer, + uint32 localprinter, uint32 type, + POLICY_HND *handle, struct in_addr *client_ip) { WERROR result; @@ -2609,7 +2620,7 @@ static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer, uint32 l fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */ - if(!spoolss_connect_to_client(¬ify_cli, unix_printer)) + if(!spoolss_connect_to_client(¬ify_cli, client_ip, unix_printer)) return False; message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list); @@ -2658,6 +2669,7 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE uint32 printerlocal = q_u->printerlocal; int snum = -1; SPOOL_NOTIFY_OPTION *option = q_u->option; + struct in_addr client_ip; /* store the notify value in the printer struct */ @@ -2687,10 +2699,12 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE else if ( (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) && !get_printer_snum(p, handle, &snum) ) return WERR_BADFID; + + client_ip.s_addr = inet_addr(p->conn->client_address); if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine, Printer->notify.printerlocal, 1, - &Printer->notify.client_hnd)) + &Printer->notify.client_hnd, &client_ip)) return WERR_SERVER_UNAVAILABLE; Printer->notify.client_connected=True; -- cgit From 04bb7e808ae391d207afb2d87e55ea0d20659dd4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 23:29:23 +0000 Subject: cleanup lanman printing= for win98; device type is LPT1:; patch by Steve L. (This used to be commit beedde03fcdd37b567661d96d97efaac640601bd) --- source3/smbd/reply.c | 2 +- source3/smbd/service.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c4e95b7562..0b710d6401 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -271,7 +271,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if ( IS_IPC(conn) ) server_devicetype = "IPC"; else if ( IS_PRINT(conn) ) - server_devicetype = "LPT:"; + server_devicetype = "LPT1:"; else server_devicetype = "A:"; diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 146212701e..18a92bc82f 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -229,7 +229,7 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev) if (dev[0] == '?' || !dev[0]) { if (lp_print_ok(snum)) { - fstrcpy(dev,"LPT:"); + fstrcpy(dev,"LPT1:"); } else if (strequal(lp_fstype(snum), "IPC")) { fstrcpy(dev, "IPC"); } else { @@ -240,7 +240,7 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev) strupper(dev); if (lp_print_ok(snum)) { - if (!strequal(dev, "LPT:")) { + if (!strequal(dev, "LPT1:")) { return NT_STATUS_BAD_DEVICE_TYPE; } } else if (strequal(lp_fstype(snum), "IPC")) { @@ -253,7 +253,7 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev) /* Behave as a printer if we are supposed to */ if (lp_print_ok(snum) && (strcmp(dev, "A:") == 0)) { - fstrcpy(dev, "LPT:"); + fstrcpy(dev, "LPT1:"); } return NT_STATUS_OK; -- cgit From 5b51fc4f065e9e68eefb530eb99ad8da9f4e5d28 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 23:32:00 +0000 Subject: smbcquota patch from metze (This used to be commit 74fab8f0d24004b1dfd5ce0fd7402895652f941f) --- source3/Makefile.in | 24 +- source3/include/fake_file.h | 46 ++++ source3/include/ntquotas.h | 97 +++++++ source3/include/smb.h | 71 +++-- source3/include/trans2.h | 6 +- source3/lib/util_str.c | 6 +- source3/libsmb/clifile.c | 17 +- source3/libsmb/clifsinfo.c | 76 ++++++ source3/libsmb/cliquota.c | 633 ++++++++++++++++++++++++++++++++++++++++++++ source3/python/py_smb.c | 4 +- source3/torture/nbio.c | 4 +- source3/torture/torture.c | 157 +++++------ source3/torture/utable.c | 4 +- source3/utils/smbcquotas.c | 545 ++++++++++++++++++++++++++++++++++++++ 14 files changed, 1562 insertions(+), 128 deletions(-) create mode 100644 source3/include/fake_file.h create mode 100644 source3/include/ntquotas.h create mode 100644 source3/libsmb/clifsinfo.c create mode 100644 source3/libsmb/cliquota.c create mode 100644 source3/utils/smbcquotas.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 641294790d..b7a2519ce7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -127,7 +127,7 @@ BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \ bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \ bin/profiles@EXEEXT@ bin/smbgroupedit@EXEEXT@ bin/ntlm_auth@EXEEXT@ \ - bin/editreg@EXEEXT@ + bin/editreg@EXEEXT@ bin/smbcquotas@EXEEXT@ TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \ bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \ @@ -215,6 +215,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \ libsmb/clistr.o libsmb/smb_signing.o \ + libsmb/cliquota.o libsmb/clifsinfo.o \ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \ libsmb/passchange.o libsmb/doserr.o \ @@ -532,6 +533,11 @@ SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \ $(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \ $(POPT_LIB_OBJ) +SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ + $(PARAM_OBJ) \ + $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \ + $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) + TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ) RPCTORTURE_OBJ = torture/rpctorture.o \ @@ -640,6 +646,8 @@ locktest : SHOWFLAGS bin/locktest@EXEEXT@ smbcacls : SHOWFLAGS bin/smbcacls@EXEEXT@ +smbcquotas : SHOWFLAGS bin/smbcquotas@EXEEXT@ + locktest2 : SHOWFLAGS bin/locktest2@EXEEXT@ rpctorture : SHOWFLAGS bin/rpctorture@EXEEXT@ @@ -840,6 +848,10 @@ bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) +bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) + bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) @@ -888,16 +900,16 @@ bin/smbwrapper.32.@SHLIBEXT@: $(PICOBJS32) bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS) @echo Linking libsmbclient shared library $@ - $(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \ $(KRB5LIBS) @SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR) bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS) @echo Linking libsmbclient non-shared library $@ - -$(AR) -rc $@ $(LIBSMBCLIENT_PICOBJS) + @-$(AR) -rc $@ $(LIBSMBCLIENT_PICOBJS) bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS) @echo Linking bigballofmud shared library $@ - $(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \ @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) $(PASSDBLIBS) $(ADSLIBS) # It would be nice to build a static bigballofmud too, but when I try @@ -1079,10 +1091,10 @@ bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ) @echo "Linking shared library $@" - $(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc + @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc bin/libmsrpc.a: $(LIBMSRPC_PICOBJ) - -$(AR) -rc $@ $(LIBMSRPC_PICOBJ) + @-$(AR) -rc $@ $(LIBMSRPC_PICOBJ) bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy @echo Linking $@ diff --git a/source3/include/fake_file.h b/source3/include/fake_file.h new file mode 100644 index 0000000000..3fe60072e9 --- /dev/null +++ b/source3/include/fake_file.h @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + FAKE FILE suppport, for faking up special files windows want access to + Copyright (C) Stefan (metze) Metzmacher 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _FAKE_FILE_H +#define _FAKE_FILE_H + +enum FAKE_FILE_TYPE { + FAKE_FILE_TYPE_NONE = 0, + FAKE_FILE_TYPE_QUOTA +}; + +#define FAKE_FILE_NAME_QUOTA "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION" + +typedef struct _FAKE_FILE_HANDLE { + enum FAKE_FILE_TYPE type; + TALLOC_CTX *mem_ctx; + void *pd; /* for private data */ + void (*free_pd)(void **pd); /* free private_data */ +} FAKE_FILE_HANDLE; + +typedef struct _FAKE_FILE { + const char *name; + enum FAKE_FILE_TYPE type; + void *(*init_pd)(TALLOC_CTX *men_ctx); + void (*free_pd)(void **pd); +} FAKE_FILE; + + +#endif /* _FAKE_FILE_H */ diff --git a/source3/include/ntquotas.h b/source3/include/ntquotas.h new file mode 100644 index 0000000000..1425e59bb8 --- /dev/null +++ b/source3/include/ntquotas.h @@ -0,0 +1,97 @@ +/* + Unix SMB/CIFS implementation. + NT QUOTA code constants + Copyright (C) Stefan (metze) Metzmacher 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _NTQUOTAS_H +#define _NTQUOTAS_H + +/* + * details for Quota Flags: + * + * 0x20 Log Limit: log if the user exceeds his Hard Quota + * 0x10 Log Warn: log if the user exceeds his Soft Quota + * 0x02 Deny Disk: deny disk access when the user exceeds his Hard Quota + * 0x01 Enable Quotas: enable quota for this fs + * + */ + +#define QUOTAS_ENABLED 0x0001 +#define QUOTAS_DENY_DISK 0x0002 +#define QUOTAS_LOG_VIOLATIONS 0x0004 +#define CONTENT_INDEX_DISABLED 0x0008 +#define QUOTAS_LOG_THRESHOLD 0x0010 +#define QUOTAS_LOG_LIMIT 0x0020 +#define LOG_VOLUME_THRESHOLD 0x0040 +#define LOG_VOLUME_LIMIT 0x0080 +#define QUOTAS_INCOMPLETE 0x0100 +#define QUOTAS_REBUILDING 0x0200 +#define QUOTAS_0400 0x0400 +#define QUOTAS_0800 0x0800 +#define QUOTAS_1000 0x1000 +#define QUOTAS_2000 0x2000 +#define QUOTAS_4000 0x4000 +#define QUOTAS_8000 0x8000 + +#define SMB_NTQUOTAS_NO_LIMIT ((SMB_BIG_UINT)(-1)) +#define SMB_NTQUOTAS_NO_ENTRY ((SMB_BIG_UINT)(-2)) +#define SMB_NTQUOTAS_NO_SPACE ((SMB_BIG_UINT)(0)) +#define SMB_NTQUOTAS_1_B (SMB_BIG_UINT)0x0000000000000001 +#define SMB_NTQUOTAS_1KB (SMB_BIG_UINT)0x0000000000000400 +#define SMB_NTQUOTAS_1MB (SMB_BIG_UINT)0x0000000000100000 +#define SMB_NTQUOTAS_1GB (SMB_BIG_UINT)0x0000000040000000 +#define SMB_NTQUOTAS_1TB (SMB_BIG_UINT)0x0000010000000000 +#define SMB_NTQUOTAS_1PB (SMB_BIG_UINT)0x0004000000000000 +#define SMB_NTQUOTAS_1EB (SMB_BIG_UINT)0x1000000000000000 + +enum SMB_QUOTA_TYPE { + SMB_INVALID_QUOTA_TYPE = -1, + SMB_USER_FS_QUOTA_TYPE = 1, + SMB_USER_QUOTA_TYPE = 2, + SMB_GROUP_FS_QUOTA_TYPE = 3,/* not used yet */ + SMB_GROUP_QUOTA_TYPE = 4 /* not in use yet, maybe for disk_free queries */ +}; + +typedef struct _SMB_NTQUOTA_STRUCT { + enum SMB_QUOTA_TYPE qtype; + SMB_BIG_UINT usedspace; + SMB_BIG_UINT softlim; + SMB_BIG_UINT hardlim; + enum SMB_QUOTA_TYPE qflags; + DOM_SID sid; +} SMB_NTQUOTA_STRUCT; + +typedef struct _SMB_NTQUOTA_LIST { + struct _SMB_NTQUOTA_LIST *prev,*next; + TALLOC_CTX *mem_ctx; + uid_t uid; + SMB_NTQUOTA_STRUCT *quotas; +} SMB_NTQUOTA_LIST; + +typedef struct _SMB_NTQUOTA_HANDLE { + BOOL valid; + SMB_NTQUOTA_LIST *quota_list; + SMB_NTQUOTA_LIST *tmp_list; +} SMB_NTQUOTA_HANDLE; + +#define CHECK_NTQUOTA_HANDLE_OK(fsp,conn) (FNUM_OK(fsp,conn) &&\ + (fsp)->fake_file_handle &&\ + ((fsp)->fake_file_handle->type == FAKE_FILE_TYPE_QUOTA) &&\ + (fsp)->fake_file_handle->pd) + +#endif /*_NTQUOTAS_H */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 02b5b9435e..62cc95ecb0 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -238,6 +238,8 @@ typedef struct nttime_info #define MAXSUBAUTHS 15 /* max sub authorities in a SID */ #endif +#define SID_MAX_SIZE ((size_t)(8+(MAXSUBAUTHS*4))) + /* SID Types */ enum SID_NAME_USE { @@ -366,6 +368,7 @@ typedef struct SMB_STRUCT_STAT *statinfo; } smb_filename; +#include "fake_file.h" typedef struct files_struct { @@ -402,6 +405,8 @@ typedef struct files_struct char *fsp_name; } files_struct; +#include "ntquotas.h" + /* used to hold an arbitrary blob of data */ typedef struct data_blob { uint8 *data; @@ -972,23 +977,23 @@ struct bitmap { #define TRANSACT_WAITNAMEDPIPEHANDLESTATE 0x53 /* These are the TRANS2 sub commands */ -#define TRANSACT2_OPEN 0 -#define TRANSACT2_FINDFIRST 1 -#define TRANSACT2_FINDNEXT 2 -#define TRANSACT2_QFSINFO 3 -#define TRANSACT2_SETFSINFO 4 -#define TRANSACT2_QPATHINFO 5 -#define TRANSACT2_SETPATHINFO 6 -#define TRANSACT2_QFILEINFO 7 -#define TRANSACT2_SETFILEINFO 8 -#define TRANSACT2_FSCTL 9 -#define TRANSACT2_IOCTL 0xA -#define TRANSACT2_FINDNOTIFYFIRST 0xB -#define TRANSACT2_FINDNOTIFYNEXT 0xC -#define TRANSACT2_MKDIR 0xD -#define TRANSACT2_SESSION_SETUP 0xE -#define TRANSACT2_GET_DFS_REFERRAL 0x10 -#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11 +#define TRANSACT2_OPEN 0x00 +#define TRANSACT2_FINDFIRST 0x01 +#define TRANSACT2_FINDNEXT 0x02 +#define TRANSACT2_QFSINFO 0x03 +#define TRANSACT2_SETFSINFO 0x04 +#define TRANSACT2_QPATHINFO 0x05 +#define TRANSACT2_SETPATHINFO 0x06 +#define TRANSACT2_QFILEINFO 0x07 +#define TRANSACT2_SETFILEINFO 0x08 +#define TRANSACT2_FSCTL 0x09 +#define TRANSACT2_IOCTL 0x0A +#define TRANSACT2_FINDNOTIFYFIRST 0x0B +#define TRANSACT2_FINDNOTIFYNEXT 0x0C +#define TRANSACT2_MKDIR 0x0D +#define TRANSACT2_SESSION_SETUP 0x0E +#define TRANSACT2_GET_DFS_REFERRAL 0x10 +#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11 /* These are the NT transact sub commands. */ #define NT_TRANSACT_CREATE 1 @@ -997,6 +1002,13 @@ struct bitmap { #define NT_TRANSACT_NOTIFY_CHANGE 4 #define NT_TRANSACT_RENAME 5 #define NT_TRANSACT_QUERY_SECURITY_DESC 6 +#define NT_TRANSACT_GET_USER_QUOTA 7 +#define NT_TRANSACT_SET_USER_QUOTA 8 + +/* These are the NT transact_get_user_quota sub commands */ +#define TRANSACT_GET_USER_QUOTA_LIST_CONTINUE 0x0000 +#define TRANSACT_GET_USER_QUOTA_LIST_START 0x0100 +#define TRANSACT_GET_USER_QUOTA_FOR_SID 0x0101 /* Relevant IOCTL codes */ #define IOCTL_QUERY_JOB_INFO 0x530060 @@ -1237,18 +1249,23 @@ struct bitmap { #define RENAME_REPLACE_IF_EXISTS 1 /* Filesystem Attributes. */ -#define FILE_CASE_SENSITIVE_SEARCH 0x01 -#define FILE_CASE_PRESERVED_NAMES 0x02 -#define FILE_UNICODE_ON_DISK 0x04 +#define FILE_CASE_SENSITIVE_SEARCH 0x00000001 +#define FILE_CASE_PRESERVED_NAMES 0x00000002 +#define FILE_UNICODE_ON_DISK 0x00000004 /* According to cifs9f, this is 4, not 8 */ /* Acconding to testing, this actually sets the security attribute! */ -#define FILE_PERSISTENT_ACLS 0x08 -/* These entries added from cifs9f --tsb */ -#define FILE_FILE_COMPRESSION 0x10 -#define FILE_VOLUME_QUOTAS 0x20 -/* I think this is wrong. JRA #define FILE_DEVICE_IS_MOUNTED 0x20 */ -#define FILE_VOLUME_SPARSE_FILE 0x40 -#define FILE_VOLUME_IS_COMPRESSED 0x8000 +#define FILE_PERSISTENT_ACLS 0x00000008 +#define FILE_FILE_COMPRESSION 0x00000010 +#define FILE_VOLUME_QUOTAS 0x00000020 +#define FILE_SUPPORTS_SPARSE_FILES 0x00000040 +#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080 +#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100 +#define FS_LFN_APIS 0x00004000 +#define FILE_VOLUME_IS_COMPRESSED 0x00008000 +#define FILE_SUPPORTS_OBJECT_IDS 0x00010000 +#define FILE_SUPPORTS_ENCRYPTION 0x00020000 +#define FILE_NAMED_STREAMS 0x00040000 +#define FILE_READ_ONLY_VOLUME 0x00080000 /* ChangeNotify flags. */ #define FILE_NOTIFY_CHANGE_FILE 0x001 diff --git a/source3/include/trans2.h b/source3/include/trans2.h index 3468d3b995..2ccf83478b 100644 --- a/source3/include/trans2.h +++ b/source3/include/trans2.h @@ -206,7 +206,9 @@ Byte offset Type name description #define SMB_QUERY_FS_SIZE_INFO 0x103 #define SMB_QUERY_FS_DEVICE_INFO 0x104 #define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105 - +#if 0 +#define SMB_QUERY_FS_QUOTA_INFO +#endif #define l2_vol_fdateCreation 0 #define l2_vol_cch 4 @@ -320,7 +322,7 @@ Byte offset Type name description #define SMB_FS_SIZE_INFORMATION 1003 #define SMB_FS_DEVICE_INFORMATION 1004 #define SMB_FS_ATTRIBUTE_INFORMATION 1005 -#define SMB_FS_CONTROL_INFORMATION 1006 +#define SMB_FS_QUOTA_INFORMATION 1006 #define SMB_FS_FULL_SIZE_INFORMATION 1007 #define SMB_FS_OBJECTID_INFORMATION 1008 diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index e2f9f19f58..e561d15f61 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1226,12 +1226,12 @@ char *binary_string(char *buf, int len) return ret; } -#if 0 + /** Just a typesafety wrapper for snprintf into a fstring. **/ -static int fstr_sprintf(fstring s, const char *fmt, ...) +int fstr_sprintf(fstring s, const char *fmt, ...) { va_list ap; int ret; @@ -1241,7 +1241,7 @@ static int fstr_sprintf(fstring s, const char *fmt, ...) va_end(ap); return ret; } -#endif + #ifndef HAVE_STRNDUP /** diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 4eb5efe193..b771e135f4 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -375,9 +375,11 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) Used in smbtorture. ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess, +int cli_nt_create_full(struct cli_state *cli, const char *fname, + uint32 CreatFlags, uint32 DesiredAccess, uint32 FileAttributes, uint32 ShareAccess, - uint32 CreateDisposition, uint32 CreateOptions) + uint32 CreateDisposition, uint32 CreateOptions, + uint8 SecuityFlags) { char *p; int len; @@ -393,9 +395,9 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA SSVAL(cli->outbuf,smb_vwv0,0xFF); if (cli->use_oplocks) - SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); - else - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); + CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); + + SIVAL(cli->outbuf,smb_ntcreate_Flags, CreatFlags); SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes); @@ -403,6 +405,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition); SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions); SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); + SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecuityFlags); p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ @@ -433,8 +436,8 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) { - return cli_nt_create_full(cli, fname, DesiredAccess, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0); + return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0); } /**************************************************************************** diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c new file mode 100644 index 0000000000..00fe189e9a --- /dev/null +++ b/source3/libsmb/clifsinfo.c @@ -0,0 +1,76 @@ +/* + Unix SMB/CIFS implementation. + FS info functions + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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" + + +BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + + if (!cli||!fs_attr) + smb_panic("cli_get_fs_attr_info() called with NULL Pionter!"); + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_QUERY_FS_ATTRIBUTE_INFO); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 12) { + goto cleanup; + } + + *fs_attr = IVAL(rdata,0); + + /* todo: but not yet needed + * return the other stuff + */ + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c new file mode 100644 index 0000000000..a56a6bd674 --- /dev/null +++ b/source3/libsmb/cliquota.c @@ -0,0 +1,633 @@ +/* + Unix SMB/CIFS implementation. + client quota functions + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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" + +BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum) +{ + *quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA, + 0x00000016, DESIRED_ACCESS_PIPE, + 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, 0x00000000, 0x03); + + if (*quota_fnum == (-1)) { + return False; + } + + return True; +} + +void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list) +{ + if (!qt_list) + return; + + if ((*qt_list)->mem_ctx) + talloc_destroy((*qt_list)->mem_ctx); + + (*qt_list) = NULL; + + return; +} + +static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt) +{ + int sid_len; + SMB_NTQUOTA_STRUCT qt; + + ZERO_STRUCT(qt); + + if (!rdata||!offset||!pqt) + smb_panic("parse_quota_record: called with NULL POINTER!\n"); + + if (rdata_count < 40) { + return False; + } + + /* offset to next quota record. + * 4 bytes IVAL(rdata,0) + * unused here... + */ + *offset = IVAL(rdata,0); + + /* sid len */ + sid_len = IVAL(rdata,4); + + if (rdata_count < 40+sid_len) { + return False; + } + + /* unknown 8 bytes in pdata + * maybe its the change time in NTTIME + */ + + /* the used space 8 bytes (SMB_BIG_UINT)*/ + qt.usedspace = (SMB_BIG_UINT)IVAL(rdata,16); +#ifdef LARGE_SMB_OFF_T + qt.usedspace |= (((SMB_BIG_UINT)IVAL(rdata,20)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,20) != 0)&& + ((qt.usedspace != 0xFFFFFFFF)|| + (IVAL(rdata,20)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + return False; + } +#endif /* LARGE_SMB_OFF_T */ + + /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ + qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24); +#ifdef LARGE_SMB_OFF_T + qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,28) != 0)&& + ((qt.softlim != 0xFFFFFFFF)|| + (IVAL(rdata,28)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + return False; + } +#endif /* LARGE_SMB_OFF_T */ + + /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ + qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32); +#ifdef LARGE_SMB_OFF_T + qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,36) != 0)&& + ((qt.hardlim != 0xFFFFFFFF)|| + (IVAL(rdata,36)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + return False; + } +#endif /* LARGE_SMB_OFF_T */ + + sid_parse(rdata+40,sid_len,&qt.sid); + + qt.qtype = SMB_USER_QUOTA_TYPE; + + *pqt = qt; + + return True; +} + +BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char params[16]; + unsigned int data_len; + char data[SID_MAX_SIZE+8]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned int sid_len; + unsigned int offset; + + if (!cli||!pqt) + smb_panic("cli_get_user_quota() called with NULL Pointer!"); + + setup = NT_TRANSACT_GET_USER_QUOTA; + + SSVAL(params, 0,quota_fnum); + SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID); + SIVAL(params, 4,0x00000024); + SIVAL(params, 8,0x00000000); + SIVAL(params,12,0x00000024); + + sid_len = sid_size(&pqt->sid); + data_len = sid_len+8; + SIVAL(data, 0, 0x00000000); + SIVAL(data, 4, sid_len); + sid_linearize(data+8, sid_len, &pqt->sid); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_GET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 16, 4, + data, data_len, 112)) { + DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) { + ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt); + } else { + DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n")); + ret = False; + } + + cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return ret; +} + +BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char params[2]; + char data[112]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned int sid_len; + memset(data,'\0',112); + + if (!cli||!pqt) + smb_panic("cli_set_user_quota() called with NULL Pointer!"); + + setup = NT_TRANSACT_SET_USER_QUOTA; + + SSVAL(params,0,quota_fnum); + + sid_len = sid_size(&pqt->sid); + SIVAL(data,0,0); + SIVAL(data,4,sid_len); + SBIG_UINT(data, 8,(SMB_BIG_UINT)0); + SBIG_UINT(data,16,pqt->usedspace); + SBIG_UINT(data,24,pqt->softlim); + SBIG_UINT(data,32,pqt->hardlim); + sid_linearize(data+40, sid_len, &pqt->sid); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_SET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 2, 0, + data, 112, 0)) { + DEBUG(1,("Failed to send NT_TRANSACT_SET_USER_QUOTA\n")); + goto cleanup; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("NT_TRANSACT_SET_USER_QUOTA failed\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return ret; +} + +BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list) +{ + BOOL ret = False; + uint16 setup; + char params[16]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned int offset; + const char *curdata = NULL; + unsigned int curdata_count = 0; + TALLOC_CTX *mem_ctx = NULL; + SMB_NTQUOTA_STRUCT qt; + SMB_NTQUOTA_LIST *tmp_list_ent; + + if (!cli||!pqt_list) + smb_panic("cli_list_user_quota() called with NULL Pointer!"); + + setup = NT_TRANSACT_GET_USER_QUOTA; + + SSVAL(params, 0,quota_fnum); + SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START); + SIVAL(params, 4,0x00000000); + SIVAL(params, 8,0x00000000); + SIVAL(params,12,0x00000000); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_GET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 16, 4, + NULL, 0, 2048)) { + DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count == 0) { + *pqt_list = NULL; + return True; + } + + if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) { + DEBUG(0,("talloc_init() failed\n")); + return (-1); + } + + offset = 1; + for (curdata=rdata,curdata_count=rdata_count; + ((curdata)&&(curdata_count>=8)&&(offset>0)); + curdata +=offset,curdata_count -= offset) { + ZERO_STRUCT(qt); + if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { + DEBUG(1,("Failed to parse the quota record\n")); + goto cleanup; + } + + if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + return (-1); + } + + if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + return (-1); + } + + memcpy(tmp_list_ent->quotas,&qt,sizeof(qt)); + tmp_list_ent->mem_ctx = mem_ctx; + + DLIST_ADD((*pqt_list),tmp_list_ent); + } + + SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE); + while(1) { + if (!cli_send_nt_trans(cli, + NT_TRANSACT_GET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 16, 4, + NULL, 0, 2048)) { + DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count == 0) { + break; + } + + offset = 1; + for (curdata=rdata,curdata_count=rdata_count; + ((curdata)&&(curdata_count>=8)&&(offset>0)); + curdata +=offset,curdata_count -= offset) { + ZERO_STRUCT(qt); + if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { + DEBUG(1,("Failed to parse the quota record\n")); + goto cleanup; + } + + if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + talloc_destroy(mem_ctx); + goto cleanup; + } + + if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + talloc_destroy(mem_ctx); + goto cleanup; + } + + memcpy(tmp_list_ent->quotas,&qt,sizeof(qt)); + tmp_list_ent->mem_ctx = mem_ctx; + + DLIST_ADD((*pqt_list),tmp_list_ent); + } + } + + + ret = True; + cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + +BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + SMB_NTQUOTA_STRUCT qt; + ZERO_STRUCT(qt); + + if (!cli||!pqt) + smb_panic("cli_get_fs_quota_info() called with NULL Pointer!"); + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_FS_QUOTA_INFORMATION); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 48) { + goto cleanup; + } + + /* unknown_1 24 NULL bytes in pdata*/ + + /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ + qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24); +#ifdef LARGE_SMB_OFF_T + qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,28) != 0)&& + ((qt.softlim != 0xFFFFFFFF)|| + (IVAL(rdata,28)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + goto cleanup; + } +#endif /* LARGE_SMB_OFF_T */ + + /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ + qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32); +#ifdef LARGE_SMB_OFF_T + qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,36) != 0)&& + ((qt.hardlim != 0xFFFFFFFF)|| + (IVAL(rdata,36)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + goto cleanup; + } +#endif /* LARGE_SMB_OFF_T */ + + /* quota_flags 2 bytes **/ + qt.qflags = SVAL(rdata,40); + + qt.qtype = SMB_USER_FS_QUOTA_TYPE; + + *pqt = qt; + + ret = True; +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + +BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char param[4]; + char data[48]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + SMB_NTQUOTA_STRUCT qt; + ZERO_STRUCT(qt); + memset(data,'\0',48); + + if (!cli||!pqt) + smb_panic("cli_set_fs_quota_info() called with NULL Pointer!"); + + setup = TRANSACT2_SETFSINFO; + + SSVAL(param,0,quota_fnum); + SSVAL(param,2,SMB_FS_QUOTA_INFORMATION); + + /* Unknown1 24 NULL bytes*/ + + /* Default Soft Quota 8 bytes */ + SBIG_UINT(data,24,pqt->softlim); + + /* Default Hard Quota 8 bytes */ + SBIG_UINT(data,32,pqt->hardlim); + + /* Quota flag 2 bytes */ + SSVAL(data,40,pqt->qflags); + + /* Unknown3 6 NULL bytes */ + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 4, 0, + data, 48, 0)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + +static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric) +{ + static fstring buffer; + + memset(buffer,'\0',sizeof(buffer)); + + if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) { + fstr_sprintf(buffer,"NO LIMIT"); + return buffer; + } +#if defined(HAVE_LONGLONG) + fstr_sprintf(buffer,"%llu",val); +#else + fstr_sprintf(buffer,"%lu",val); +#endif + return buffer; +} + +void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) +{ + if (!qt) + smb_panic("dump_ntquota() called with NULL pointer"); + + switch (qt->qtype) { + case SMB_USER_FS_QUOTA_TYPE: + { + d_printf("File System QUOTAS:\n"); + d_printf("Limits:\n"); + d_printf(" Default Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric)); + d_printf(" Default Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric)); + d_printf("Quota Flags:\n"); + d_printf(" Quotas Enabled: %s\n", + ((qt->qflags"AS_ENABLED)||(qt->qflags"AS_DENY_DISK))?"On":"Off"); + d_printf(" Deny Disk: %s\n",(qt->qflags"AS_DENY_DISK)?"On":"Off"); + d_printf(" Log Soft Limit: %s\n",(qt->qflags"AS_LOG_THRESHOLD)?"On":"Off"); + d_printf(" Log Hard Limit: %s\n",(qt->qflags"AS_LOG_LIMIT)?"On":"Off"); + } + break; + case SMB_USER_QUOTA_TYPE: + { + fstring username_str = {0}; + + if (_sidtostring) { + _sidtostring(username_str,&qt->sid,_numeric); + } else { + fstrcpy(username_str,sid_string_static(&qt->sid)); + } + + if (_verbose) { + d_printf("Quotas for User: %s\n",username_str); + d_printf("Used Space: %15s\n",quota_str_static(qt->usedspace,False,_numeric)); + d_printf("Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric)); + d_printf("Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric)); + } else { + d_printf("%-30s: ",username_str); + d_printf("%15s/",quota_str_static(qt->usedspace,False,_numeric)); + d_printf("%15s/",quota_str_static(qt->softlim,True,_numeric)); + d_printf("%15s\n",quota_str_static(qt->hardlim,True,_numeric)); + } + } + break; + default: + d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype); + return; + } +} + +void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) +{ + SMB_NTQUOTA_LIST *cur; + + for (cur = *qtl;cur;cur = cur->next) { + if (cur->quotas) + dump_ntquota(cur->quotas,_verbose,_numeric,_sidtostring); + } +} diff --git a/source3/python/py_smb.c b/source3/python/py_smb.c index 8d81176e4d..d37b73cceb 100644 --- a/source3/python/py_smb.c +++ b/source3/python/py_smb.c @@ -165,8 +165,8 @@ static PyObject *py_smb_nt_create_andx(PyObject *self, PyObject *args, return NULL; result = cli_nt_create_full( - cli->cli, filename, desired_access, file_attributes, - share_access, create_disposition, create_options); + cli->cli, filename, 0, desired_access, file_attributes, + share_access, create_disposition, create_options, 0); if (cli_is_error(cli->cli)) { PyErr_SetString(PyExc_RuntimeError, "nt_create_andx failed"); diff --git a/source3/torture/nbio.c b/source3/torture/nbio.c index 2d519b40ba..d8d3ca0c09 100644 --- a/source3/torture/nbio.c +++ b/source3/torture/nbio.c @@ -148,12 +148,12 @@ void nb_createx(char *fname, desired_access = FILE_READ_DATA | FILE_WRITE_DATA; } - fd = cli_nt_create_full(c, fname, + fd = cli_nt_create_full(c, fname, 0, desired_access, 0x0, FILE_SHARE_READ|FILE_SHARE_WRITE, create_disposition, - create_options); + create_options, 0); if (fd == -1 && handle != -1) { printf("ERROR: cli_nt_create_full failed for %s - %s\n", fname, cli_errstr(c)); diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 5ff7c3bb2d..00d5b86ff8 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -2778,9 +2778,9 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE, FILE_OVERWRITE_IF, - FILE_DELETE_ON_CLOSE); + FILE_DELETE_ON_CLOSE, 0); if (fnum1 == -1) { printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2808,9 +2808,9 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, - FILE_OVERWRITE_IF, 0); + FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2846,8 +2846,8 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2858,8 +2858,8 @@ static BOOL run_deletetest(int dummy) /* This should fail with a sharing violation - open for delete is only compatible with SHARE_DELETE. */ - fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0); + fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0); if (fnum2 != -1) { printf("[3] open - 2 of %s succeeded - should have failed.\n", fname); @@ -2869,8 +2869,8 @@ static BOOL run_deletetest(int dummy) /* This should succeed. */ - fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); + fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0); if (fnum2 == -1) { printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2914,8 +2914,8 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -2924,8 +2924,8 @@ static BOOL run_deletetest(int dummy) } /* This should succeed. */ - fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); + fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0); if (fnum2 == -1) { printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1)); correct = False; @@ -2945,8 +2945,9 @@ static BOOL run_deletetest(int dummy) } /* This should fail - no more opens once delete on close set. */ - fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); + fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OPEN, 0, 0); if (fnum2 != -1) { printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname ); correct = False; @@ -2991,9 +2992,9 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA, + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - FILE_OVERWRITE_IF, 0); + FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3021,8 +3022,8 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, - FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3077,8 +3078,9 @@ static BOOL run_deletetest(int dummy) cli_sockopt(cli1, sockops); - fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3086,8 +3088,9 @@ static BOOL run_deletetest(int dummy) goto fail; } - fnum2 = cli_nt_create_full(cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OPEN, 0, 0); if (fnum2 == -1) { printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1)); @@ -3123,8 +3126,8 @@ static BOOL run_deletetest(int dummy) printf("eighth delete on close test succeeded.\n"); /* This should fail - we need to set DELETE_ACCESS. */ - fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE); + fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0); if (fnum1 != -1) { printf("[9] open of %s succeeded should have failed!\n", fname); @@ -3134,8 +3137,8 @@ static BOOL run_deletetest(int dummy) printf("ninth delete on close test succeeded.\n"); - fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0); if (fnum1 == -1) { printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1)); correct = False; @@ -3243,20 +3246,20 @@ static BOOL run_xcopy(int dummy) return False; } - fnum1 = cli_nt_create_full(cli1, fname, + fnum1 = cli_nt_create_full(cli1, fname, 0, FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE, FILE_OVERWRITE_IF, - 0x4044); + 0x4044, 0); if (fnum1 == -1) { printf("First open failed - %s\n", cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli1, fname, + fnum2 = cli_nt_create_full(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, - 0x200000); + 0x200000, 0); if (fnum2 == -1) { printf("second open failed - %s\n", cli_errstr(cli1)); return False; @@ -3288,8 +3291,8 @@ static BOOL run_rename(int dummy) cli_unlink(cli1, fname); cli_unlink(cli1, fname1); - fnum1 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("First open failed - %s\n", cli_errstr(cli1)); @@ -3310,11 +3313,11 @@ static BOOL run_rename(int dummy) cli_unlink(cli1, fname); cli_unlink(cli1, fname1); - fnum1 = cli_nt_create_full(cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, #if 0 - FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); #else - FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0); + FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0); #endif if (fnum1 == -1) { @@ -3337,8 +3340,8 @@ static BOOL run_rename(int dummy) cli_unlink(cli1, fname); cli_unlink(cli1, fname1); - fnum1 = cli_nt_create_full(cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("Third open failed - %s\n", cli_errstr(cli1)); @@ -3350,8 +3353,8 @@ static BOOL run_rename(int dummy) { int fnum2; - fnum2 = cli_nt_create_full(cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum2 == -1) { printf("Fourth open failed - %s\n", cli_errstr(cli1)); @@ -3405,8 +3408,8 @@ static BOOL run_pipe_number(int dummy) cli_sockopt(cli1, sockops); while(1) { - fnum = cli_nt_create_full(cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0); + fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0); if (fnum == -1) { printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1)); @@ -3594,16 +3597,16 @@ static BOOL run_opentest(int dummy) printf("TEST #1 testing 2 non-io opens (no delete)\n"); - fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OPEN_IF, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0); if (fnum2 == -1) { printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3625,16 +3628,16 @@ static BOOL run_opentest(int dummy) printf("TEST #2 testing 2 non-io opens (first with delete)\n"); - fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OPEN_IF, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0); if (fnum2 == -1) { printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3656,16 +3659,16 @@ static BOOL run_opentest(int dummy) printf("TEST #3 testing 2 non-io opens (second with delete)\n"); - fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OPEN_IF, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0); if (fnum2 == -1) { printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3687,16 +3690,16 @@ static BOOL run_opentest(int dummy) printf("TEST #4 testing 2 non-io opens (both with delete)\n"); - fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OPEN_IF, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0); if (fnum2 != -1) { printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2)); @@ -3716,16 +3719,16 @@ static BOOL run_opentest(int dummy) printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n"); - fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_DELETE, FILE_OPEN_IF, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0); if (fnum2 == -1) { printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3748,16 +3751,16 @@ static BOOL run_opentest(int dummy) cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ, FILE_OPEN_IF, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, FILE_OPEN_IF, 0, 0); if (fnum2 == -1) { printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2)); @@ -3780,16 +3783,16 @@ static BOOL run_opentest(int dummy) cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1)); return False; } - fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0); + fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0); if (fnum2 != -1) { printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2)); @@ -3893,8 +3896,8 @@ static BOOL run_openattrtest(int dummy) for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) { cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname,FILE_WRITE_DATA, open_attrs_table[i], - FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i], + FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0); if (fnum1 == -1) { printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1)); @@ -3907,8 +3910,8 @@ static BOOL run_openattrtest(int dummy) } for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) { - fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j], - FILE_SHARE_NONE, FILE_OVERWRITE, 0); + fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j], + FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0); if (fnum1 == -1) { for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) { @@ -4220,8 +4223,8 @@ static BOOL run_dirtest1(int dummy) for (i=0;i<1000;i++) { fstring fname; slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i); - fnum = cli_nt_create_full(cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0); + fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0); if (fnum == -1) { fprintf(stderr,"Failed to open %s\n", fname); return False; diff --git a/source3/torture/utable.c b/source3/torture/utable.c index 74d5f164c0..3ec5932b79 100644 --- a/source3/torture/utable.c +++ b/source3/torture/utable.c @@ -144,11 +144,11 @@ BOOL torture_casetable(int dummy) printf("%04x (%c)\n", c, isprint(c)?c:'.'); fname = form_name(c); - fnum = cli_nt_create_full(cli, fname, + fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, - FILE_OPEN_IF, 0); + FILE_OPEN_IF, 0, 0); if (fnum == -1) { printf("Failed to create file with char %04x\n", c); diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c new file mode 100644 index 0000000000..c5d0aa869b --- /dev/null +++ b/source3/utils/smbcquotas.c @@ -0,0 +1,545 @@ +/* + Unix SMB/CIFS implementation. + QUOTA get/set utility + + Copyright (C) Andrew Tridgell 2000 + Copyright (C) Tim Potter 2000 + Copyright (C) Jeremy Allison 2000 + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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" + +static pstring server; + +/* numeric is set when the user wants numeric SIDs and ACEs rather + than going via LSA calls to resolve them */ +static BOOL numeric; +static BOOL verbose; + +enum todo_values {NOOP_QUOTA=0,FS_QUOTA,USER_QUOTA,LIST_QUOTA,SET_QUOTA}; +enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR}; + +static struct cli_state *cli_ipc = NULL; +static POLICY_HND pol; +static BOOL got_policy_hnd; + +static struct cli_state *connect_one(const char *share); + +/* Open cli connection and policy handle */ + +static BOOL cli_open_policy_hnd(void) +{ + /* Initialise cli LSA connection */ + + if (!cli_ipc) { + cli_ipc = connect_one("IPC$"); + if (!cli_nt_session_open (cli_ipc, PI_LSARPC)) { + return False; + } + } + + /* Open policy handle */ + + if (!got_policy_hnd) { + + /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, + but NT sends 0x2000000 so we might as well do it too. */ + + if (!NT_STATUS_IS_OK(cli_lsa_open_policy(cli_ipc, cli_ipc->mem_ctx, True, + GENERIC_EXECUTE_ACCESS, &pol))) { + return False; + } + + got_policy_hnd = True; + } + + return True; +} + +/* convert a SID to a string, either numeric or username/group */ +static void SidToString(fstring str, DOM_SID *sid, BOOL _numeric) +{ + char **domains = NULL; + char **names = NULL; + uint32 *types = NULL; + + sid_to_string(str, sid); + + if (_numeric) return; + + /* Ask LSA to convert the sid to a name */ + + if (!cli_open_policy_hnd() || + !NT_STATUS_IS_OK(cli_lsa_lookup_sids(cli_ipc, cli_ipc->mem_ctx, + &pol, 1, sid, &domains, + &names, &types)) || + !domains || !domains[0] || !names || !names[0]) { + return; + } + + /* Converted OK */ + + slprintf(str, sizeof(fstring) - 1, "%s%s%s", + domains[0], lp_winbind_separator(), + names[0]); + +} + +/* convert a string to a SID, either numeric or username/group */ +static BOOL StringToSid(DOM_SID *sid, const char *str) +{ + uint32 *types = NULL; + DOM_SID *sids = NULL; + BOOL result = True; + + if (strncmp(str, "S-", 2) == 0) { + return string_to_sid(sid, str); + } + + if (!cli_open_policy_hnd() || + !NT_STATUS_IS_OK(cli_lsa_lookup_names(cli_ipc, cli_ipc->mem_ctx, + &pol, 1, &str, &sids, + &types))) { + result = False; + goto done; + } + + sid_copy(sid, &sids[0]); + done: + + return result; +} + +#define QUOTA_GET 1 +#define QUOTA_SETLIM 2 +#define QUOTA_SETFLAGS 3 +#define QUOTA_LIST 4 + +enum {PARSE_FLAGS,PARSE_LIM}; + +static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA_TYPE *qtype, int *cmd, SMB_NTQUOTA_STRUCT *pqt) +{ + char *p = set_str,*p2; + int todo; + BOOL stop = False; + BOOL enable = False; + BOOL deny = False; + + if (strncasecmp(set_str,"UQLIM:",6)==0) { + p += 6; + *qtype = SMB_USER_QUOTA_TYPE; + *cmd = QUOTA_SETLIM; + todo = PARSE_LIM; + if ((p2=strstr(p,":"))==NULL) { + return -1; + } + + *p2 = '\0'; + p2++; + + fstrcpy(username_str,p); + p = p2; + } else if (strncasecmp(set_str,"FSQLIM:",7)==0) { + p +=7; + *qtype = SMB_USER_FS_QUOTA_TYPE; + *cmd = QUOTA_SETLIM; + todo = PARSE_LIM; + } else if (strncasecmp(set_str,"FSQFLAGS:",9)==0) { + p +=9; + todo = PARSE_FLAGS; + *qtype = SMB_USER_FS_QUOTA_TYPE; + *cmd = QUOTA_SETFLAGS; + } else { + return -1; + } + + switch (todo) { + case PARSE_LIM: +#if defined(HAVE_LONGLONG) + if (sscanf(p,"%llu/%llu",&pqt->softlim,&pqt->hardlim)!=2) { +#else + if (sscanf(p,"%lu/%lu",&pqt->softlim,&pqt->hardlim)!=2) { +#endif + return -1; + } + + break; + case PARSE_FLAGS: + while (!stop) { + + if ((p2=strstr(p,"/"))==NULL) { + stop = True; + } else { + *p2 = '\0'; + p2++; + } + + if (strncasecmp(p,"QUOTA_ENABLED",13)==0) { + enable = True; + } else if (strncasecmp(p,"DENY_DISK",9)==0) { + deny = True; + } else if (strncasecmp(p,"LOG_SOFTLIMIT",13)==0) { + pqt->qflags |= QUOTAS_LOG_THRESHOLD; + } else if (strncasecmp(p,"LOG_HARDLIMIT",13)==0) { + pqt->qflags |= QUOTAS_LOG_LIMIT; + } else { + return -1; + } + + p=p2; + } + + if (deny) { + pqt->qflags |= QUOTAS_DENY_DISK; + } else if (enable) { + pqt->qflags |= QUOTAS_ENABLED; + } + + break; + } + + return 0; +} + +static int do_quota(struct cli_state *cli, enum SMB_QUOTA_TYPE qtype, uint16 cmd, pstring username_str, SMB_NTQUOTA_STRUCT *pqt) +{ + uint32 fs_attrs = 0; + int quota_fnum = 0; + SMB_NTQUOTA_LIST *qtl = NULL; + SMB_NTQUOTA_STRUCT qt; + ZERO_STRUCT(qt); + + if (!cli_get_fs_attr_info(cli, &fs_attrs)) { + d_printf("Failed to get the filesystem attributes %s.\n", + cli_errstr(cli)); + return -1; + } + + if (!(fs_attrs & FILE_VOLUME_QUOTAS)) { + d_printf("Quotas are not supported by the server.\n"); + return 0; + } + + if (!cli_get_quota_handle(cli, "a_fnum)) { + d_printf("Failed to open \\%s %s.\n", + FAKE_FILE_NAME_QUOTA,cli_errstr(cli)); + return -1; + } + + switch(qtype) { + case SMB_USER_QUOTA_TYPE: + if (!StringToSid(&qt.sid, username_str)) { + d_printf("StringToSid() failed for [%s]\n",username_str); + return -1; + } + + switch(cmd) { + case QUOTA_GET: + if (!cli_get_user_quota(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + dump_ntquota(&qt,verbose,numeric,SidToString); + break; + case QUOTA_SETLIM: + pqt->sid = qt.sid; + if (!cli_set_user_quota(cli, quota_fnum, pqt)) { + d_printf("%s cli_set_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + if (!cli_get_user_quota(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + dump_ntquota(&qt,verbose,numeric,SidToString); + break; + case QUOTA_LIST: + if (!cli_list_user_quota(cli, quota_fnum, &qtl)) { + d_printf("%s cli_set_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + dump_ntquota_list(&qtl,verbose,numeric,SidToString); + free_ntquota_list(&qtl); + break; + default: + d_printf("Unknown Error\n"); + return -1; + } + break; + case SMB_USER_FS_QUOTA_TYPE: + switch(cmd) { + case QUOTA_GET: + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + dump_ntquota(&qt,True,numeric,NULL); + break; + case QUOTA_SETLIM: + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + qt.softlim = pqt->softlim; + qt.hardlim = pqt->hardlim; + if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_set_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + dump_ntquota(&qt,True,numeric,NULL); + break; + case QUOTA_SETFLAGS: + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + qt.qflags = pqt->qflags; + if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_set_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + dump_ntquota(&qt,True,numeric,NULL); + break; + default: + d_printf("Unknown Error\n"); + return -1; + } + break; + default: + d_printf("Unknown Error\n"); + return -1; + } + + cli_close(cli, quota_fnum); + + return 0; +} + +/***************************************************** +return a connection to a server +*******************************************************/ +static struct cli_state *connect_one(const char *share) +{ + struct cli_state *c; + struct in_addr ip; + NTSTATUS nt_status; + zero_ip(&ip); + + if (!cmdline_auth_info.got_pass) { + char *pass = getpass("Password: "); + if (pass) { + pstrcpy(cmdline_auth_info.password, pass); + cmdline_auth_info.got_pass = True; + } + } + + if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server, + &ip, 0, + share, "?????", + cmdline_auth_info.username, lp_workgroup(), + cmdline_auth_info.password, 0, NULL))) { + return c; + } else { + DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); + return NULL; + } +} + +/**************************************************************************** + main program +****************************************************************************/ + int main(int argc, const char *argv[]) +{ + char *share; + int opt; + int result; + int todo = 0; + pstring username_str = {0}; + pstring path = {0}; + pstring set_str = {0}; + enum SMB_QUOTA_TYPE qtype; + int cmd = 0; + BOOL test_args = False; + struct cli_state *cli; + BOOL fix_user = False; + SMB_NTQUOTA_STRUCT qt; + poptContext pc; + struct poptOption long_options[] = { + POPT_AUTOHELP + { "user", 'u', POPT_ARG_STRING, NULL, 'u', "Show quotas for user", "user" }, + { "list", 'L', POPT_ARG_NONE, NULL, 'L', "List user quotas" }, + { "fs", 'F', POPT_ARG_NONE, NULL, 'F', "Show filesystem quotas" }, + { "set", 'S', POPT_ARG_STRING, NULL, 'S', "Set acls\n\ +SETSTRING:\n\ +UQLIM:// for user quotas\n\ +FSQLIM:/ for filesystem defaults\n\ +FSQFLAGS:QUOTA_ENABLED/DENY_DISK/LOG_SOFTLIMIT/LOG_HARD_LIMIT", "SETSTRING" }, + { "numeric", 'n', POPT_ARG_NONE, &numeric, True, "Don't resolve sids or limits to names" }, + { "verbose", 'v', POPT_ARG_NONE, &verbose, True, "be verbose" }, + { "test-args", 't', POPT_ARG_NONE, &test_args, True, "Test arguments"}, + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS + { NULL } + }; + + ZERO_STRUCT(qt); + + setlinebuf(stdout); + + dbf = x_stderr; + + fault_setup(NULL); + + setup_logging(argv[0],True); + + + lp_load(dyn_CONFIGFILE,True,False,False); + load_interfaces(); + + pc = poptGetContext("smbcquotas", argc, argv, long_options, 0); + + poptSetOtherOptionHelp(pc, "//server1/share1"); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case 'L': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + todo = LIST_QUOTA; + break; + + case 'F': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + todo = FS_QUOTA; + break; + + case 'u': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + pstrcpy(username_str,poptGetOptArg(pc)); + todo = USER_QUOTA; + fix_user = True; + break; + + case 'S': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + pstrcpy(set_str,poptGetOptArg(pc)); + todo = SET_QUOTA; + break; + } + } + + if (todo == 0) + todo = USER_QUOTA; + + if (!fix_user) + pstrcpy(username_str,cmdline_auth_info.username); + + /* Make connection to server */ + if(!poptPeekArg(pc)) { + poptPrintUsage(pc, stderr, 0); + exit(EXIT_PARSE_ERROR); + } + + pstrcpy(path, poptGetArg(pc)); + + all_string_sub(path,"/","\\",0); + + pstrcpy(server,path+2); + share = strchr_m(server,'\\'); + if (!share) { + share = strchr_m(server,'/'); + if (!share) { + printf("Invalid argument: %s\n", share); + exit(EXIT_PARSE_ERROR); + } + } + + *share = 0; + share++; + + if (todo == SET_QUOTA) { + if (parse_quota_set(set_str, username_str, &qtype, &cmd, &qt)) { + printf("Invalid argument: -S %s\n", set_str); + exit(EXIT_PARSE_ERROR); + } + } + + if (!test_args) { + cli = connect_one(share); + if (!cli) { + exit(EXIT_FAILED); + } + } else { + exit(EXIT_OK); + } + + + /* Perform requested action */ + + switch (todo) { + case FS_QUOTA: + result = do_quota(cli,SMB_USER_FS_QUOTA_TYPE, QUOTA_GET, username_str, NULL); + break; + case LIST_QUOTA: + result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_LIST, username_str, NULL); + break; + case USER_QUOTA: + result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_GET, username_str, NULL); + break; + case SET_QUOTA: + result = do_quota(cli, qtype, cmd, username_str, &qt); + break; + default: + + result = EXIT_FAILED; + break; + } + + return result; +} + -- cgit From a056cd8845989475a72ae88681cfb3c9d7b23377 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 23:50:21 +0000 Subject: * We must return 0x2 as the majorversion for nt4 to upload drivers * fix bug found by clobber_region() (This used to be commit ad2765bb5e0c1c4d8f12583e49df5b1bc7ffc389) --- source3/rpc_server/srv_spoolss_nt.c | 12 +++++++++++- source3/smbd/reply.c | 25 +++++++++++++++---------- 2 files changed, 26 insertions(+), 11 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 424d7909d1..4432b06fc7 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -2307,7 +2307,17 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint *type = 0x4; if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL) return WERR_NOMEM; - SIVAL(*data, 0, 3); + + /* Windows NT 4.0 seems to not allow uploading of drivers + to a server that reports 0x3 as the MajorVersion. + need to investigate more how Win2k gets around this . + -- jerry */ + + if ( RA_WINNT == get_remote_arch() ) + SIVAL(*data, 0, 2); + else + SIVAL(*data, 0, 3); + *needed = 0x4; return WERR_OK; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 0b710d6401..1c7e23a20f 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3042,20 +3042,22 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, Resolve wildcards in a filename rename. ********************************************************************/ -static BOOL resolve_wildcards(char *name1,char *name2) +static BOOL resolve_wildcards(const char *name1, char *name2) { fstring root1,root2; fstring ext1,ext2; - char *p,*p2; + char *p,*p2, *pname1, *pname2; + int available_space; + - name1 = strrchr_m(name1,'/'); - name2 = strrchr_m(name2,'/'); + pname1 = strrchr_m(name1,'/'); + pname2 = strrchr_m(name2,'/'); - if (!name1 || !name2) + if (!pname1 || !pname2) return(False); - fstrcpy(root1,name1); - fstrcpy(root2,name2); + fstrcpy(root1,pname1); + fstrcpy(root2,pname2); p = strrchr_m(root1,'.'); if (p) { *p = 0; @@ -3097,10 +3099,13 @@ static BOOL resolve_wildcards(char *name1,char *name2) p++; } - pstrcpy(name2,root2); + available_space = sizeof(pstring) - PTR_DIFF(pname2, name2); + + StrnCpy(pname2, root2, available_space-1); + available_space -= strlen(root2); if (ext2[0]) { - pstrcat(name2,"."); - pstrcat(name2,ext2); + strncat(pname2, ".", available_space-1); + strncat(pname2, ext2, available_space-2); } return(True); -- cgit From 7b338a49e3402d9176dbfce7c8fb22e0ceb2e21c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 23:50:49 +0000 Subject: add smbcquotas to list of ignored files (This used to be commit 71c2335239922a4c89f76d6260f1eecae36989be) --- source3/bin/.cvsignore | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/bin/.cvsignore b/source3/bin/.cvsignore index 058397a52c..86ae6b6e67 100644 --- a/source3/bin/.cvsignore +++ b/source3/bin/.cvsignore @@ -47,3 +47,4 @@ vfstest wbinfo winbindd wrepld +smbcquotas -- cgit From e8ef094df381f491f869c175f1e63704c06487be Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 12 Apr 2003 17:12:12 +0000 Subject: Patch from Armijn Hemel to fix build on FreeBSD 5 systems with a broken krb5-config (This used to be commit 741d5c3cd8870b3d06ba0225e5b24a82403eb142) --- source3/configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/configure.in b/source3/configure.in index ce53358d09..d1ca1e494b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2086,8 +2086,8 @@ LIBS="" AC_MSG_CHECKING(for working krb5-config) if test -x "$KRB5_CONFIG"; then LIBS="$LIBS `$KRB5_CONFIG --libs`" - CFLAGS="$CFLAGS `$KRB5_CONFIG --cflags`" - CPPFLAGS="$CPPFLAGS `$KRB5_CONFIG --cflags`" + CFLAGS="$CFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" + CPPFLAGS="$CPPFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" FOUND_KRB5=yes AC_MSG_RESULT(yes) else -- cgit From d5135e98864e2a1bd33c17a468ffcfd95f07e3f2 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 12 Apr 2003 17:40:17 +0000 Subject: strncat get sometimes optimized to strcat by glibc and that triggers our "don't use strcat" define reworked to snprintf (This used to be commit c37467651becedf3e6b142b53d6675e973970249) --- source3/smbd/reply.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1c7e23a20f..b2dab2fea2 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3101,11 +3101,10 @@ static BOOL resolve_wildcards(const char *name1, char *name2) available_space = sizeof(pstring) - PTR_DIFF(pname2, name2); - StrnCpy(pname2, root2, available_space-1); - available_space -= strlen(root2); if (ext2[0]) { - strncat(pname2, ".", available_space-1); - strncat(pname2, ext2, available_space-2); + snprintf(pname2, available_space - 1, "%s.%s", root2, ext2); + } else { + StrnCpy(pname2, root2, available_space - 1); } return(True); -- cgit