From e76ddf2cfddde80b22226278c301126b6accf91d Mon Sep 17 00:00:00 2001 From: Dave Daugherty Date: Wed, 2 Dec 2009 09:19:35 +0100 Subject: [PATCH] Centrify-Samba-3.3.9-Unified.diff as git patch --- source/Makefile.in | 4 +- source/include/includes.h | 2 +- source/include/proto.h | 1 + source/lib/replace/system/capability.h | 12 + source/lib/tdb/common/libtdb.c | 376 ++++++++++++++++++++++++++++++++ source/lib/tdb/include/libtdb.h | 132 +++++++++++ source/libads/kerberos_verify.c | 8 +- source/libsmb/cliconnect.c | 102 +++++++++- source/libsmb/clikrb5.c | 6 + source/modules/vfs_hpuxacl.c | 8 +- source/nsswitch/winbind_nss_hpux.h | 7 + source/param/loadparm.c | 12 + source/rpc_server/srv_srvsvc_nt.c | 51 ++++- source/script/mkversion.sh | 18 +- source/smbd/sec_ctx.c | 9 +- source/utils/smbpasswd.c | 10 +- source/utils/testparm.c | 43 ++++ source/winbindd/winbindd.c | 10 +- 18 files changed, 773 insertions(+), 38 deletions(-) create mode 100644 source/lib/tdb/common/libtdb.c create mode 100644 source/lib/tdb/include/libtdb.h diff --git a/source/Makefile.in b/source/Makefile.in index 474bc1e..1685894 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -421,7 +421,7 @@ LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \ CLDAP_OBJ = libads/cldap.o -LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ +LIBSMB_OBJ = libsmb/clientgen.o nsswitch/wb_common.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \ libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ @@ -1683,7 +1683,7 @@ LIBTDB_SHARED_TARGET_SONAME=$(LIBTDB_SHARED_TARGET).$(LIBTDB_SOVER) LIBTDB_STATIC_TARGET=@LIBTDB_STATIC_TARGET@ LIBTDB=$(LIBTDB_STATIC_TARGET) @LIBTDB_SHARED@ LIBTDB_SYMS=$(srcdir)/exports/libtdb.@SYMSEXT@ -LIBTDB_HEADERS=$(srcdir)/@tdbdir@/include/tdb.h +LIBTDB_HEADERS=$(srcdir)/@tdbdir@/include/tdb.h $(srcdir)/@tdbdir@/include/libtdb.h $(LIBTDB_SYMS): $(LIBTDB_HEADERS) @$(MKSYMS_SH) $(AWK) $@ $(LIBTDB_HEADERS) diff --git a/source/include/includes.h b/source/include/includes.h index baf22e8..5083296 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -98,9 +98,9 @@ #endif #endif /* RELIANTUNIX */ -#include "system/capability.h" #include "system/dir.h" #include "system/filesys.h" +#include "system/capability.h" #include "system/glob.h" #include "system/iconv.h" #include "system/locale.h" diff --git a/source/include/proto.h b/source/include/proto.h index 8dbab9a..a121dd0 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -5700,6 +5700,7 @@ int lp_idmap_cache_time(void); int lp_idmap_negative_cache_time(void); int lp_keepalive(void); bool lp_passdb_expand_explicit(void); +bool lp_ignore_syssetgroups_error(void); char *lp_ldap_suffix(void); char *lp_ldap_admin_dn(void); int lp_ldap_ssl(void); diff --git a/source/lib/replace/system/capability.h b/source/lib/replace/system/capability.h index a7b78f0..236a62e 100644 --- a/source/lib/replace/system/capability.h +++ b/source/lib/replace/system/capability.h @@ -37,7 +37,19 @@ #define BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND #endif +#include + +/* + * Make sure we can be included from userland by preventing + * capability.h from including other kernel headers + */ +#define _LINUX_TYPES_H +#define _LINUX_FS_H +typedef uint32_t __u32; + #include +#undef _LINUX_FS_H +#undef _LINUX_TYPES_H #ifdef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND #undef _LINUX_TYPES_H diff --git a/source/lib/tdb/common/libtdb.c b/source/lib/tdb/common/libtdb.c new file mode 100644 index 0000000..d7becd8 --- /dev/null +++ b/source/lib/tdb/common/libtdb.c @@ -0,0 +1,376 @@ +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2004 + Copyright (C) David Daugherty 2005 + + ** NOTE! The following LGPL license applies to the libtdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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 +*/ + +#define STANDALONE +#include "config.h" + +#include + +#ifdef HAVE_FCNTL_H +#include +#else +#ifdef HAVE_SYS_FCNTL_H +#include +#endif +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include + + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef TIME_WITH_SYS_TIME +#include +#include +#else +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + + +#ifdef HAVE_MEMORY_H +#include +#endif + +#ifdef HAVE_MALLOC_H +#include +#endif + +#include "tdb.h" +#include "libtdb.h" + +#ifndef EMPTY_THING +#define EMPTY_THING(s) (!s || !*s) +#endif + +#ifndef MAX_TDB_KEY_SIZE +#define MAX_TDB_KEY_SIZE 128 /* Arbitrary size */ +#endif + +/** + * get8 + * + * Get an unsigned byte from the buffer. Building block for the rest of the functions. + */ +static uint8 get8(const uint8 *p) +{ + return *p; +} + +/** + * put8 + * + * Put an unsigned byte into buffer. Building block for the rest of the functions. + */ +static void put8(uint8 *p, uint8 val) +{ + *p = val; +} + +/** + * getlohi32 + * + * Get an unsigned 32 bit value from a buffer where it is + * stored in little endian format and return it in host order. + */ +static uint32 getlohi32(const uint8 *p) +{ + return get8(p++) + (get8(p++) << 8) + (get8(p++) << 16) + (get8(p) << 24); +} + +/** + * putlohi32 + * + * Put a host-ordered unsigned 32 bit value into a buffer in little endian format + */ +static void putlohi32(uint8 *p, uint32 val) +{ + put8(p++, (uint8)val); + put8(p++, (uint8)(val >> 8)); + put8(p++, (uint8)(val >> 16)); + put8(p++, (uint8)(val >> 24)); +} + +/** + * Set the machine password info in secrets.tdb and update the last password change time. + * + * @param tdbfile - full path of the TDB file to set the password in + * @param domain - the NTLM domain name that we are changing the machine password for + * @param password - the new machine account password + * @param sec_channel - the security channel setting. See get_default_sec_channel(void) for examples + * + * @return - LIBTDB return code + */ +int libtdb_set_machineinfo(const char *tdbfile, const char *domain, const char *password, uint32 sec_channel) +{ + char key[MAX_TDB_KEY_SIZE]; + TDB_HANDLE tdb_handle; + time_t now = time(0); + int ltdbcode = LIBTDB_BAD_PARAM; + + uint8 lohi_value[8]; + + if (EMPTY_THING(tdbfile) || EMPTY_THING(domain) || EMPTY_THING(password)) + goto EXIT2; + + if ((ltdbcode = libtdb_open(tdbfile, O_RDWR|O_CREAT, 0600, &tdb_handle)) != LIBTDB_SUCCESS) + goto EXIT2; + + snprintf(key, MAX_TDB_KEY_SIZE, "SECRETS/MACHINE_PASSWORD/%s", domain); + if ((ltdbcode = libtdb_write(tdb_handle, key, CONST_CAST(void*, password), strlen(password)+1)) != LIBTDB_SUCCESS) + goto EXIT1; + + /* Really it needs to be stored little endian */ + putlohi32(lohi_value, now); + snprintf(key, MAX_TDB_KEY_SIZE, "SECRETS/MACHINE_LAST_CHANGE_TIME/%s", domain); + if ((ltdbcode = libtdb_write(tdb_handle, key, (void*)lohi_value, sizeof(now))) != LIBTDB_SUCCESS) + goto EXIT1; + + /* Really it needs to be stored little endian */ + putlohi32(lohi_value, sec_channel); + snprintf(key, MAX_TDB_KEY_SIZE, "SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s", domain); + ltdbcode = libtdb_write(tdb_handle, key, (void*)lohi_value, sizeof(sec_channel)); + +EXIT1: + libtdb_close(tdb_handle); + +EXIT2: + return ltdbcode; +} + +/** + * Get the machine password info from secrets.tdb and update the last password change time. + * + * @param tdbfile - full path of the TDB file to set the password in + * @param domain - the NTLM domain name for the information + * @param password - Place to return the passowrd in + * @param size - Size of the password buffer + * @param real_size - The actual size of the password + * @param last_pwd_change_time - Time password was last changed + * @param sec_channel - Place for the returned security channel setting + * + * @return - LIBTDB return code + */ +int libtdb_get_machineinfo(const char *tdbfile, const char *domain, char *password, size_t size, size_t *real_size, + time_t *last_pwd_change_time, uint32 *sec_channel) +{ + char key[MAX_TDB_KEY_SIZE]; + TDB_HANDLE tdb_handle; + uint8 lohi_value[8]; + + int ltdbcode = LIBTDB_BAD_PARAM; + + if (EMPTY_THING(tdbfile) || EMPTY_THING(domain) || !password) + goto EXIT2; + + if ((ltdbcode = libtdb_open(tdbfile, O_RDONLY, 0600, &tdb_handle)) != LIBTDB_SUCCESS) + goto EXIT2; + + snprintf(key, MAX_TDB_KEY_SIZE, "SECRETS/MACHINE_PASSWORD/%s", domain); + if ((ltdbcode = libtdb_read(tdb_handle, key, password, size, real_size)) != LIBTDB_SUCCESS) + goto EXIT1; + + snprintf(key, MAX_TDB_KEY_SIZE, "SECRETS/MACHINE_LAST_CHANGE_TIME/%s", domain); + if ((ltdbcode = libtdb_read(tdb_handle, key, lohi_value, + sizeof(*last_pwd_change_time), 0)) != LIBTDB_SUCCESS) + goto EXIT1; + + *last_pwd_change_time = getlohi32(lohi_value); + snprintf(key, MAX_TDB_KEY_SIZE, "SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s", domain); + ltdbcode = libtdb_read(tdb_handle, key, lohi_value, sizeof(*sec_channel), 0); + + *sec_channel= getlohi32(lohi_value); + +EXIT1: + libtdb_close(tdb_handle); + +EXIT2: + return ltdbcode; +} + +/** + * Open a TDB File + * + * @param tdbfile - full path of the TDB file to set the password in + * @param open_flags - see fcntl.h + * @param mode - file permissions to set if file was created. + * @param tdb_handle - place to return the TDB_CONTEXT. + * + * @return - LIBTDB return code + */ +int libtdb_open(const char *tdbfile, int open_flags, mode_t mode, TDB_HANDLE *tdb_handle) +{ + TDB_CONTEXT *tdb = tdb_open(tdbfile, 0, TDB_DEFAULT, open_flags, mode); + int ltdbcode = LIBTDB_SUCCESS; + + *tdb_handle = (TDB_HANDLE)tdb; + + if (tdb == NULL) + ltdbcode = LIBTDB_OPEN_FAILED; + + return ltdbcode; +} + +int libtdb_close(TDB_HANDLE tdb_handle) +{ + int ltdbcode = LIBTDB_CLOSE_FAILED; + + if (tdb_handle) + if (tdb_close((TDB_CONTEXT *)tdb_handle)) + ltdbcode = LIBTDB_SUCCESS; + + return ltdbcode; +} + +/** + * Write a TDB record + * + * @param tdb_handle - opened TDB context + * @param key - the record key + * @param data - the record data + * @param size - the record key + * + * @return - LIBTDB return code + */ +int libtdb_write(TDB_HANDLE tdb_handle, const char *key, const void *data, size_t size) +{ + TDB_DATA k; + TDB_DATA d; + int ltdbcode = LIBTDB_SUCCESS; + + k.dptr = CONST_CAST(char*, key); + k.dsize = strlen(key); + + d.dptr = CONST_CAST(char*, data); + d.dsize = size; + + if (tdb_store((TDB_CONTEXT *)tdb_handle, k, d, TDB_REPLACE) != 0) + ltdbcode = LIBTDB_WRITE_FAILED; + + return ltdbcode; +} + +/** + * Read a TDB record + * + * @param tdb_handle - opened TDB context + * @param key - the record key + * @param data - buffer to store the read data + * @param size - max size of supplied data buffer + * @param real_size - place to store the actual size of the read data. + * + * @return - LIBTDB return code + */ +int libtdb_read(TDB_HANDLE tdb_handle, const char * key, void *data, size_t size, size_t *real_size) +{ + TDB_DATA k; + TDB_DATA d; + int ltdbcode = LIBTDB_SUCCESS; + + k.dptr = CONST_CAST(char*, key); + k.dsize = strlen(key); + + d = tdb_fetch(tdb_handle, k); + + if (real_size) + *real_size = d.dsize; + + if (d.dsize == 0) + ltdbcode = LIBTDB_NO_DATA; + else if (d.dsize > size) + ltdbcode = LIBTDB_BUF_TOO_SMALL; + else + memcpy(data, d.dptr, d.dsize); + + if (d.dptr) + free(d.dptr); + + return ltdbcode; +} + +/** + * This function gets called for each record found in the TDB that we are traversing + * @param tc - Open TDB context + * @param key - The key of the current record + * @param data - The data of the current record + * @param state - the client's state parameter - in this case a pointer to a traverse_control structure. + * + * @return - LIBTDB return code + */ +static int libtdb_traverse_callback(TDB_CONTEXT *tc, TDB_DATA key, TDB_DATA data, void *state) +{ + traverse_control *tctl = (traverse_control*)state; + + tctl->handle = (TDB_HANDLE)tc; + tctl->key = key.dptr; + tctl->keysize = key.dsize; + tctl->data = (void *)data.dptr; + tctl->datasize = data.dsize; + + return tctl->callback(tctl); +} + +/** + * Traverse a Samba database file, reading each record sequentially. + * + * @param tdbfile - the TDB file to traverse + * @param tctl - Control structure for the traverse + * @param count - Place to store the number of records read. + * @return ltdcode - See libtdb.h for codes + */ +int libtdb_traverse(const char *tdbfile, traverse_control *tctl) +{ + TDB_HANDLE tdb_handle; + int ltdbcode = LIBTDB_BAD_PARAM; + + if (EMPTY_THING(tdbfile) || !tctl) + goto EXIT; + + if ((ltdbcode = libtdb_open(tdbfile, O_RDONLY, 0600, &tdb_handle)) != LIBTDB_SUCCESS) + goto EXIT; + + tctl->count = tdb_traverse((TDB_CONTEXT *)tdb_handle, libtdb_traverse_callback, (void*)tctl); + + if (tctl->count == -1) + ltdbcode = LIBTDB_TRAVERSE_FAILED; + + libtdb_close(tdb_handle); + +EXIT: + return ltdbcode; +} diff --git a/source/lib/tdb/include/libtdb.h b/source/lib/tdb/include/libtdb.h new file mode 100644 index 0000000..d911fe3 --- /dev/null +++ b/source/lib/tdb/include/libtdb.h @@ -0,0 +1,132 @@ +#ifndef __LIBTDB_H__ +#define __LIBTDB_H__ + +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2004 + Copyright (C) David Daugherty 2005 + + ** NOTE! The following LGPL license applies to the libtdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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 +*/ + +/* + * NOTE!! + * This code implements thin wrappers around the LGPL'd tdb source code and + * is used to generate libtdb.so that can be used by commercial packages. + * Please take care NOT to include any GPL'd code here! + * + * Further: Do not add any definitions to this file that make other Samba + * headers (including tdb.h) to be necessary for compilation. + */ + +#include "config.h" + +/*** + * SIZEOF_type is determined by configure + ***/ +#ifndef SIZEOF_SHORT +#define SIZEOF_SHORT 2 +#endif +#ifndef SIZEOF_INT +#define SIZEOF_INT 4 +#endif +#ifndef SIZEOF_LONG +#define SIZEOF_LONG 4 +#endif + +#if !defined(uint8) +# define uint8 unsigned char +#endif + +#if !defined(uint32) +#if (SIZEOF_INT == 4) +#define uint32 unsigned int +#elif (SIZEOF_LONG == 4) +#define uint32 unsigned long +#elif (SIZEOF_SHORT == 4) +#define uint32 unsigned short +#endif +#endif + +#if !defined(TRUE) +#define TRUE (1) +#endif + +#if !defined(FALSE) +#define FALSE (0) +#endif + +/* This does not seem to work to avoid GNU compiler warnings - too bad! */ +#ifndef CONST_CAST +#define CONST_CAST(type, ptr) ((type) ((void *) (ptr))) +#endif + +/* LIBTDB Return Codes */ +#define LIBTDB_SUCCESS 0 /* Success */ +#define LIBTDB_OPEN_FAILED 1 /* Opening the TDB File failed */ +#define LIBTDB_CLOSE_FAILED 2 /* Closing the TDB File failed */ +#define LIBTDB_READ_FAILED 3 /* Reading the TDB File failed */ +#define LIBTDB_WRITE_FAILED 4 /* Writing the TDB File failed */ +#define LIBTDB_BUF_TOO_SMALL 5 /* The return buffer needs to be bigger */ +#define LIBTDB_BAD_PARAM 6 /* Missing or bad parameter */ +#define LIBTDB_NO_DATA 7 /* No data was read (bad key?) */ +#define LIBTDB_TRAVERSE_FAILED 8 /* Traversing a TDB file failed */ + +typedef void* TDB_HANDLE; /* Hide the definition of TDB_CONTEXT from the outside world */ + +typedef struct traverse_control +{ + int count; /* Number of records traversed */ + TDB_HANDLE handle; /* The TDB handle used to traverse the file */ + char *key; /* The current key (for each callback) */ + int keysize; /* The current key size */ + void *data; /* The current data */ + int datasize; /* The current data size */ + int (*callback)(struct traverse_control *); /* The function to call for each record */ + void *param1; /* Client private data area to recover context */ + void *param2; /* Client private data area to recover context */ + void *param3; /* Client private data area to recover context */ + void *param4; /* Client private data area to recover context */ +} traverse_control; + + +#ifdef __cplusplus +extern "C" { +#endif + +int libtdb_set_machineinfo(const char *tdbfile, const char *domain, const char *password, uint32 sec_channel); + +int libtdb_get_machineinfo(const char *tdbfile, const char *domain, char *password, size_t size, size_t *real_size, + time_t *last_set_time, uint32 *sec_channel); + +int libtdb_open(const char *tdbfile, int open_flags, mode_t mode, TDB_HANDLE *tdb_handle); +int libtdb_close(TDB_HANDLE tdb_handle); +int libtdb_read(TDB_HANDLE tdb_handle, const char *key, void *data, size_t size, size_t *real_size); +int libtdb_write(TDB_HANDLE tdb_handle, const char *key, const void *data, size_t datasize); +int libtdb_traverse(const char *tdbfile, traverse_control *tctl); + + +#ifdef __cplusplus +} +#endif + +#endif /* __LIBTDB_H__ */ diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c index de3fdeb..64c8f56 100644 --- a/source/libads/kerberos_verify.c +++ b/source/libads/kerberos_verify.c @@ -227,7 +227,13 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, bool auth_ok = False; char *password_s = NULL; krb5_data password; - krb5_enctype enctypes[] = { + krb5_enctype enctypes[] = { +#ifdef ENCTYPE_AES128_CTS_HMAC_SHA1_96 + ENCTYPE_AES128_CTS_HMAC_SHA1_96, +#endif +#ifdef ENCTYPE_AES256_CTS_HMAC_SHA1_96 + ENCTYPE_AES256_CTS_HMAC_SHA1_96, +#endif #if defined(ENCTYPE_ARCFOUR_HMAC) ENCTYPE_ARCFOUR_HMAC, #endif diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c index 3e076b2..2543c46 100644 --- a/source/libsmb/cliconnect.c +++ b/source/libsmb/cliconnect.c @@ -37,6 +37,59 @@ static const struct { {-1,NULL} }; +/*get sid of the user by uid*/ +static bool get_sid(uid_t uid,fstring sid) +{ + + struct winbindd_request request; + struct winbindd_response response; + + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + if (!sid) + return False; + + memset(sid,0,sizeof(fstring)); + + if (uid == -1) + return False; + /* Send request */ + request.data.uid = uid; + if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) != NSS_STATUS_SUCCESS) + return False; + + memcpy(sid,response.data.sid.sid,sizeof(fstring)-1); + + return True; +} + +/*get the sam account of the user by sid*/ +static bool get_sam_account(fstring sid,fstring sam) +{ + struct winbindd_request request; + struct winbindd_response response; + + memset(sam,0,sizeof(fstring)); + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + if (!sam) + return False; + if (!sid||!sid[0]) + return False; + + fstrcpy(request.data.sid, sid); + if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) != NSS_STATUS_SUCCESS) + return False; + + memcpy(sam, response.data.name.name, sizeof(fstring) -1); + + return True; +} + + static const char *star_smbserver_name = "*SMBSERVER"; /** @@ -957,7 +1010,54 @@ ntlmssp: account[PTR_DIFF(p,user)] = '\0'; } - return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain)); + /* + * We are here because: + * 1. Kerberos authentication failed , now trying to authenticate again using NTLM, + * 2. We are told to do NTLM authentication, + * and NTLM authentication require user's samAccountName. + * We must get it first. + */ + { + fstring sid; + fstring samAccountName; + + /*get userinfo*/ + struct passwd *unpasswd = NULL; + + unpasswd = getpwnam(account); + + if (unpasswd) + { + DEBUG(10,("Get user info success.")); + DEBUGADD(10, ("user name=%s,uid=%u,gid=%u\n",unpasswd->pw_name,unpasswd->pw_uid,unpasswd->pw_gid)); + + /*get sid*/ + if (get_sid(unpasswd->pw_uid,sid)) + { + DEBUG(10,("Get user sid success.sid=%s",sid)); + /*get sam account*/ + if (get_sam_account(sid,samAccountName)) + { + DEBUG(10,("Get user samAccountName success.samAccountName=%s",samAccountName)); + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, samAccountName, pass, user_domain)); + } + else + { + DEBUG(3,("Get user samAccountName failed.sid=%s",sid)); + } + } + else + { + DEBUG(3,("Get user sid failed: user name=%s,uid=%u,gid=%u",unpasswd->pw_name,unpasswd->pw_uid,unpasswd->pw_gid)); + } + } + else + { + DEBUG(3,("Get user info failed.user name=%s",account)); + } + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, + user_domain)); + } } /**************************************************************************** diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index 1e2fe01..d3ab20d 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -806,6 +806,12 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, krb5_ccache ccdef = NULL; krb5_auth_context auth_context = NULL; krb5_enctype enc_types[] = { +#ifdef ENCTYPE_AES128_CTS_HMAC_SHA1_96 + ENCTYPE_AES128_CTS_HMAC_SHA1_96, +#endif +#ifdef ENCTYPE_AES256_CTS_HMAC_SHA1_96 + ENCTYPE_AES256_CTS_HMAC_SHA1_96, +#endif #ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC, #endif diff --git a/source/modules/vfs_hpuxacl.c b/source/modules/vfs_hpuxacl.c index f929340..c643409 100644 --- a/source/modules/vfs_hpuxacl.c +++ b/source/modules/vfs_hpuxacl.c @@ -253,7 +253,7 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, goto done; } if (S_ISDIR(s.st_mode)) { - HPUX_ACL_T other_acl; + HPUX_ACL_T other_acl = NULL; int other_count; SMB_ACL_TYPE_T other_type; @@ -349,9 +349,9 @@ int hpuxacl_sys_acl_set_fd(vfs_handle_struct *handle, int hpuxacl_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path) { - SMB_ACL_T smb_acl; + SMB_ACL_T smb_acl = NULL; int ret = -1; - HPUX_ACL_T hpux_acl; + HPUX_ACL_T hpux_acl = NULL; int count; DEBUG(10, ("entering hpuxacl_sys_acl_delete_def_file.\n")); @@ -486,7 +486,7 @@ static bool smb_acl_to_hpux_acl(SMB_ACL_T smb_acl, static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpux_acl, int count, SMB_ACL_TYPE_T type) { - SMB_ACL_T result; + SMB_ACL_T result = NULL; int i; if ((result = sys_acl_init(0)) == NULL) { diff --git a/source/nsswitch/winbind_nss_hpux.h b/source/nsswitch/winbind_nss_hpux.h index 62cf3c2..c501e9d 100644 --- a/source/nsswitch/winbind_nss_hpux.h +++ b/source/nsswitch/winbind_nss_hpux.h @@ -117,6 +117,13 @@ union nss_XbyY_key { void *ether; }; +/* /usr/include/netdb.h defines h_errno as a macro. + If that has been done, undefine because of the name conflict with + the h_errno field in this struct. */ +#ifdef _REENTRANT +#undef h_errno +#endif + typedef struct nss_XbyY_args { nss_XbyY_buf_t buf; int stayopen; diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 491264e..8712485 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -195,6 +195,7 @@ struct global { bool bWinbindOfflineLogon; bool bWinbindNormalizeNames; bool bWinbindRpcOnly; + bool bIgnoreSysSetGroupsError; char *szIdmapBackend; char *szIdmapAllocBackend; char *szAddShareCommand; @@ -4199,6 +4200,15 @@ static struct parm_struct parm_table[] = { .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL, }, { + .label = "ignore syssetgroups error", + .type = P_BOOL, + .p_class = P_GLOBAL, + .ptr = &Globals.bIgnoreSysSetGroupsError, + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL, + }, + { .label = "panic action", .type = P_STRING, .p_class = P_GLOBAL, @@ -4730,6 +4740,7 @@ static void init_globals(bool first_time_only) Globals.bObeyPamRestrictions = False; Globals.syslog = 1; Globals.bSyslogOnly = False; + Globals.bIgnoreSysSetGroupsError = False; Globals.bTimestampLogs = True; string_set(&Globals.szLogLevel, "0"); Globals.bDebugPrefixTimestamp = False; @@ -5116,6 +5127,7 @@ FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime) FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime) FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive) FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit) +FN_GLOBAL_BOOL(lp_ignore_syssetgroups_error, &Globals.bIgnoreSysSetGroupsError) FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix) FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index 5df3daa..0427c6f 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -521,9 +521,38 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, num_services = lp_numservices(); unbecome_root(); + /* Check the existence of the path */ + bool *lp_pathexist = TALLOC_ZERO_ARRAY(ctx, bool, num_services); + W_ERROR_HAVE_NO_MEMORY(lp_pathexist); + /* Count the number of entries. */ for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + lp_pathexist[snum] = True; + if (lp_pathname(snum) != NULL) + { + /*check if the path exists.if it does not exist, then set to non-browseable*/ + /* expand the path first, for it may contain some variable such as %u %m */ + SMB_STRUCT_STAT sbuf; + char *path = talloc_asprintf(ctx, "%s", lp_pathname(snum)); + path = talloc_sub_advanced( + ctx, lp_servicename(snum), + get_current_username(), lp_pathname(snum), + p->pipe_user.ut.uid, get_current_username(), + "", path); + + if (sys_stat(path, &sbuf) != 0) + { + DEBUG(3, ("init_srv_share_info_ctr: stat of %s failed. %s\n", path, strerror(errno))); + lp_pathexist[snum] = False; + } + + if (!S_ISDIR(sbuf.st_mode)) + { + DEBUG(3,("init_srv_share_info_ctr: %s is not a directory.\n", path)); + lp_pathexist[snum] = False; + } + } + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { DEBUG(10, ("counting service %s\n", lp_servicename(snum))); num_entries++; } else { @@ -547,7 +576,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum); } @@ -564,7 +593,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum); } @@ -581,7 +610,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum); } @@ -598,7 +627,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum); } @@ -615,7 +644,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum); } @@ -632,7 +661,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum); } @@ -649,7 +678,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum); } @@ -666,7 +695,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum); } @@ -683,7 +712,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum); } @@ -700,7 +729,7 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array); for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && + if (lp_pathexist[snum] && lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) && (resume_handle <= (i + valid_share_count++)) ) { init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum); } diff --git a/source/script/mkversion.sh b/source/script/mkversion.sh index 08b3a38..5aa8abf 100755 --- a/source/script/mkversion.sh +++ b/source/script/mkversion.sh @@ -27,11 +27,10 @@ SAMBA_VERSION_IS_GIT_SNAPSHOT=`sed -n 's/^SAMBA_VERSION_IS_GIT_SNAPSHOT=//p' $SO SAMBA_VERSION_RELEASE_NICKNAME=`sed -n 's/^SAMBA_VERSION_RELEASE_NICKNAME=//p' $SOURCE_DIR$VERSION_FILE` -SAMBA_VERSION_VENDOR_SUFFIX=`sed -n 's/^SAMBA_VERSION_VENDOR_SUFFIX=//p' $SOURCE_DIR$VERSION_FILE` +#SAMBA_VERSION_VENDOR_SUFFIX=`sed -n 's/^SAMBA_VERSION_VENDOR_SUFFIX=//p' $SOURCE_DIR$VERSION_FILE` +SAMBA_VERSION_VENDOR_SUFFIX="\"cdc-${CENTRIFY_VERSION_NUMBER}-${CENTRIFY_BUILD_NUMBER}\"" SAMBA_VERSION_VENDOR_PATCH=`sed -n 's/^SAMBA_VERSION_VENDOR_PATCH=//p' $SOURCE_DIR$VERSION_FILE` -SAMBA_VERSION_VENDOR_FUNCTION=`sed -n 's/^SAMBA_VERSION_VENDOR_FUNCTION=//p' $SOURCE_DIR$VERSION_FILE` - echo "/* Autogenerated by script/mkversion.sh */" > $OUTPUT_FILE echo "#define SAMBA_VERSION_MAJOR ${SAMBA_VERSION_MAJOR}" >> $OUTPUT_FILE @@ -75,10 +74,10 @@ if test x"${SAMBA_VERSION_IS_GIT_SNAPSHOT}" = x"yes";then if test x"${HAVEVER}" != x"yes" -a -d "${SOURCE_DIR}../.git";then HAVEGIT=no GIT_INFO=`git show --pretty=format:"%h%n%ct%n%H%n%cd" --stat HEAD 2>/dev/null` - GIT_COMMIT_ABBREV=`printf "%s" "${GIT_INFO}" | sed -n 1p` - GIT_COMMIT_TIME=`printf "%s" "${GIT_INFO}" | sed -n 2p` - GIT_COMMIT_FULLREV=`printf "%s" "${GIT_INFO}" | sed -n 3p` - GIT_COMMIT_DATE=`printf "%s" "${GIT_INFO}" | sed -n 4p` + GIT_COMMIT_ABBREV=`echo -e "${GIT_INFO}" | sed -n 1p` + GIT_COMMIT_TIME=`echo -e "${GIT_INFO}" | sed -n 2p` + GIT_COMMIT_FULLREV=`echo -e "${GIT_INFO}" | sed -n 3p` + GIT_COMMIT_DATE=`echo -e "${GIT_INFO}" | sed -n 4p` if test -n "${GIT_COMMIT_ABBREV}";then HAVEGIT=yes HAVEVER=yes @@ -103,16 +102,11 @@ echo "#define SAMBA_VERSION_OFFICIAL_STRING \"${SAMBA_VERSION_STRING}\"" >> $OUT ## ## Add the vendor string if present ## -if test -n "${SAMBA_VERSION_VENDOR_FUNCTION}"; then - echo "#define SAMBA_VERSION_VENDOR_FUNCTION ${SAMBA_VERSION_VENDOR_FUNCTION}" >> $OUTPUT_FILE -fi - if test -n "${SAMBA_VERSION_VENDOR_SUFFIX}";then echo "#define SAMBA_VERSION_VENDOR_SUFFIX ${SAMBA_VERSION_VENDOR_SUFFIX}" >> $OUTPUT_FILE SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-${SAMBA_VERSION_VENDOR_SUFFIX}" if test -n "${SAMBA_VERSION_VENDOR_PATCH}";then echo "#define SAMBA_VERSION_VENDOR_PATCH ${SAMBA_VERSION_VENDOR_PATCH}" >> $OUTPUT_FILE - echo "#define SAMBA_VERSION_VENDOR_PATCH_STRING \"${SAMBA_VERSION_VENDOR_PATCH}\"" >> $OUTPUT_FILE SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-${SAMBA_VERSION_VENDOR_PATCH}" fi fi diff --git a/source/smbd/sec_ctx.c b/source/smbd/sec_ctx.c index a618f06..16d5330 100644 --- a/source/smbd/sec_ctx.c +++ b/source/smbd/sec_ctx.c @@ -250,15 +250,18 @@ bool push_sec_ctx(void) #ifndef HAVE_DARWIN_INITGROUPS /* Normal credential switch path. */ - static void set_unix_security_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups) { /* Start context switch */ gain_root(); #ifdef HAVE_SETGROUPS if (sys_setgroups(gid, ngroups, groups) != 0 && !non_root_mode()) { - smb_panic("sys_setgroups failed"); - } + if (lp_ignore_syssetgroups_error()){ + DEBUG(0, ("sys_setgroups failed for uid %d, with %d groups", uid, ngroups)); + } else { + smb_panic("sys_setgroups failed"); + } + } #endif become_id(uid, gid); /* end context switch */ diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c index 6f12692..cd438dd 100644 --- a/source/utils/smbpasswd.c +++ b/source/utils/smbpasswd.c @@ -504,6 +504,7 @@ static int process_nonroot(int local_flags) int result = 0; char *old_pw = NULL; char *new_pw = NULL; + fstring real_name; if (local_flags & ~(LOCAL_AM_ROOT | LOCAL_SET_PASSWORD)) { /* Extra flags that we can't honor non-root */ @@ -531,7 +532,14 @@ static int process_nonroot(int local_flags) if (remote_machine == NULL) { remote_machine = "127.0.0.1"; + fstrcpy(real_name,global_myname()); + fstrcat(real_name,"\\"); + fstrcat(real_name,user_name); } + else + { + fstrcpy(real_name,user_name); + } if (remote_machine != NULL) { old_pw = get_pass("Old SMB password:",stdin_passwd_get); @@ -548,7 +556,7 @@ static int process_nonroot(int local_flags) exit(1); } - if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name, old_pw, + if (!NT_STATUS_IS_OK(password_change(remote_machine, real_name, old_pw, new_pw, 0))) { fprintf(stderr,"Failed to change password for %s\n", user_name); result = 1; diff --git a/source/utils/testparm.c b/source/utils/testparm.c index 527db2d..a36b1d6 100644 --- a/source/utils/testparm.c +++ b/source/utils/testparm.c @@ -33,6 +33,34 @@ #include "includes.h" +#if defined(HPUX) +/***************************************************** + Prevent uid and gid from negative numbers + If found invallid uid/gid for guest account, return 1. + Otherwise return 0. + *****************************************************/ +int check_valid_guestaccount() +{ + struct passwd *pw; + fstring guser; + int ret = 0; + + fstrcpy(guser,lp_guestaccount()); + pw = sys_getpwnam(guser); + + if (!pw) { + fprintf(stderr, "ERROR: Not found the user %s as guest account from /etc/passwd\n", guser); + ret = 1; + } else { + if (pw->pw_uid < 0 || pw->pw_gid < 0) { + fprintf(stderr, "ERROR: Invalid uid/gid as guest account = %s on global due to nagetive values\n", guser); + ret = 1; + } + } + return ret; +} +#endif + extern bool AllowDebugChange; /*********************************************** @@ -191,6 +219,21 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ } #endif +#if defined(HPUX) + /* + * Protect the valid user as guest account from negative uid and gid. + * When guest account is set to a user with negative uid or gid, + * we suggest Administrator to use smbnull as guest account for HP_UX + * in smb.conf. + */ + if (check_valid_guestaccount()) + { + fprintf(stderr, "Recommend: Please use smbnull as guest account on [global]\n"); + fprintf(stderr, " or change invalid uid/gid to positive numbers.\n\n"); + ret = 1; + } +#endif /* HPUX */ + if (!lp_passdb_backend()) { fprintf(stderr,"ERROR: passdb backend must have a value or be left out\n"); } diff --git a/source/winbindd/winbindd.c b/source/winbindd/winbindd.c index 1d618e2..9d8861b 100644 --- a/source/winbindd/winbindd.c +++ b/source/winbindd/winbindd.c @@ -937,6 +937,7 @@ static void process_loop(void) } if (FD_ISSET(listen_sock, &r_fds)) { + bool has_idle = true; while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) { DEBUG(5,("winbindd: Exceeding %d client " @@ -944,6 +945,7 @@ static void process_loop(void) "connection.\n", WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); if (!remove_idle_client()) { + has_idle = false; DEBUG(0,("winbindd: Exceeding %d " "client connections, no idle " "connection found\n", @@ -952,10 +954,12 @@ static void process_loop(void) } } /* new, non-privileged connection */ - new_connection(listen_sock, False); + if (has_idle) + new_connection(listen_sock, False); } if (FD_ISSET(listen_priv_sock, &r_fds)) { + bool has_idle = true; while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) { DEBUG(5,("winbindd: Exceeding %d client " @@ -963,6 +967,7 @@ static void process_loop(void) "connection.\n", WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); if (!remove_idle_client()) { + has_idle = false; DEBUG(0,("winbindd: Exceeding %d " "client connections, no idle " "connection found\n", @@ -971,7 +976,8 @@ static void process_loop(void) } } /* new, privileged connection */ - new_connection(listen_priv_sock, True); + if (has_idle) + new_connection(listen_priv_sock, True); } no_fds_ready: -- 1.6.0.4