diff options
author | Jeremy Allison <jra@samba.org> | 2001-07-06 00:49:45 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2001-07-06 00:49:45 +0000 |
commit | fb1e289408cb8de4b8f9b988c56aa6d64df9b622 (patch) | |
tree | 9a8a56b622404f352d416cd7ddd0354f030b332e /source | |
parent | 6ad113dce11db901ff666dac9a34e74f7b763f14 (diff) | |
download | samba-fb1e289408cb8de4b8f9b988c56aa6d64df9b622.tar.gz |
Syncup getting ready for release.
Jeremy.
Diffstat (limited to 'source')
180 files changed, 15967 insertions, 8183 deletions
diff --git a/source/Makefile.in b/source/Makefile.in index 4f642994924..24d8692f987 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -39,6 +39,7 @@ LIBDIR = @libdir@ VARDIR = @localstatedir@ CONFIGDIR = @configdir@ MANDIR = @mandir@ +INCLUDEDIR = @includedir@ # The permissions to give the executables INSTALLPERMS = 0755 @@ -81,11 +82,11 @@ FLAGS32 = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS) SPROGS = bin/smbd bin/nmbd bin/swat PROGS1 = bin/smbclient bin/smbspool bin/testparm bin/testprns bin/smbstatus bin/smbcontrol @RUNPROG@ -PROGS2 = bin/smbpasswd bin/make_smbcodepage bin/rpcclient bin/make_unicodemap bin/smbcacls @WRAP@ @WRAP32@ +PROGS2 = bin/smbpasswd bin/make_smbcodepage bin/rpcclient bin/make_unicodemap bin/smbcacls @WRAP@ @WRAP32@ @PAM_MOD@ MPROGS = @MPROGS@ -PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup bin/make_printerdef +PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup -SCRIPTS = $(srcdir)/script/smbtar $(srcdir)/script/convert_smbpasswd +SCRIPTS = $(srcdir)/script/smbtar QUOTAOBJS=@QUOTAOBJS@ @@ -98,7 +99,7 @@ TDB_OBJ = tdb/tdb.o tdb/spinlock.o tdb/tdbutil.o LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \ lib/getsmbpass.o lib/interface.o lib/kanji.o lib/md4.o \ lib/interfaces.o lib/pidfile.o lib/replace.o \ - lib/signal.o lib/slprintf.o lib/system.o lib/doscalls.o lib/time.o \ + lib/signal.o lib/system.o lib/doscalls.o lib/time.o \ lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \ lib/bitmap.o lib/crc32.o lib/snprintf.o lib/wins_srv.o \ lib/util_array.o lib/util_str.o lib/util_sid.o \ @@ -119,12 +120,13 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ libsmb/clitrans.o libsmb/clisecdesc.o \ - libsmb/namequery.o libsmb/nmblib.o \ + libsmb/namequery.o libsmb/nmblib.o libsmb/clistr.o \ libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ libsmb/passchange.o libsmb/unexpected.o $(RPC_PARSE_OBJ1) LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_spoolss.o \ + libsmb/cli_netlogon.o libsmb/cli_srvsvc.o \ rpc_client/cli_pipe.o RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \ @@ -133,7 +135,8 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \ rpc_server/srv_samr.o rpc_server/srv_samr_nt.o rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o \ rpc_server/srv_util.o rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o \ rpc_server/srv_pipe.o rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o \ - rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o + rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o \ + lib/util_getent.o # this includes only the low level parse code, not stuff # that requires knowledge of security contexts @@ -166,6 +169,7 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ + smbd/utmp.o smbd/session.o \ smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \ smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \ smbd/message.o smbd/nttrans.o smbd/pipes.o \ @@ -241,7 +245,8 @@ SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) \ $(UBIQX_OBJ) $(RPC_PARSE_OBJ) $(RPC_CLIENT_OBJ) $(LIB_OBJ) RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_spoolss.o \ - rpcclient/cmd_samr.o rpcclient/cmd_lsarpc.o + rpcclient/cmd_samr.o rpcclient/cmd_lsarpc.o \ + rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ @@ -258,6 +263,8 @@ SMBW_OBJ = smbwrapper/smbw.o \ SMBWRAPPER_OBJ = $(SMBW_OBJ) smbwrapper/wrapped.o +LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o $(LIB_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) + CLIENT_OBJ = client/client.o client/clitar.o \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(READLINE_OBJ) @@ -325,6 +332,21 @@ NSS_OBJ = $(NSS_OBJ_0:.o=.po) PICOBJS = $(SMBWRAPPER_OBJ:.o=.po) PICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32) +PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \ + pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \ + lib/debug.o lib/util_sid.o lib/messages.o lib/util_str.o \ + lib/wins_srv.o lib/substitute.o lib/select.o lib/util.o \ + nsswitch/wb_client.o nsswitch/wb_common.o lib/system.o \ + lib/charset.o lib/util_file.o lib/kanji.o lib/genrand.o \ + lib/username.o lib/charcnv.o lib/time.o lib/md4.o \ + lib/util_unistr.o lib/signal.o lib/talloc.o lib/ms_fnmatch.o \ + lib/util_sock.o lib/doscalls.o lib/smbrun.o lib/util_sec.o \ + ubiqx/ubi_sLinkList.o libsmb/smbencrypt.o libsmb/smbdes.o \ + $(PARAM_OBJ) $(TDB_OBJ) $(PASSDB_OBJ) + +PAM_SMBPASS_OBJ = $(PAM_SMBPASS_OBJ_0:.o=.po) +LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.po) + WINBINDD_OBJ1 = \ nsswitch/winbindd.o \ nsswitch/winbindd_user.o \ @@ -356,6 +378,8 @@ NSS_OBJ = $(NSS_OBJ_0:.o=.po) all : CHECK $(SPROGS) $(PROGS) +pam_smbpass : CHECK bin/pam_smbpass.@SHLIBEXT@ + smbwrapper : CHECK bin/smbsh bin/smbwrapper.@SHLIBEXT@ @WRAP32@ smbtorture : CHECK bin/smbtorture @@ -558,33 +582,45 @@ bin/smbwrapper.32.@SHLIBEXT@: $(PICOBJS32) @echo Linking shared library $@ @$(LD) -32 @LDSHFLAGS@ -o $@ $(PICOBJS32) $(LIBS) +bin/libsmbclient.so: $(LIBSMBCLIENT_PICOBJS) + @echo Linking libsmbclient shared library $@ + @$(LD) -shared -o $@ $(LIBSMBCLIENT_PICOBJS) $(LIBS) # Anything else? + bin/smbsh: $(SMBSH_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBSH_OBJ) $(LDFLAGS) $(LIBS) +bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_OBJ) + @echo Linking shared library $@ + $(LD) @LDSHFLAGS@ -symbolic -o $@ $(PAM_SMBPASS_OBJ) -lpam $(LIBS) -lc + nsswitch/libnss_wins.so: $(NSS_OBJ) @echo "Linking $@" @$(LD) @LDSHFLAGS@ -o $@ $(NSS_OBJ) -lc -bin/winbindd: $(WINBINDD_OBJ) bin/.dummy - @echo Linking $@ - @$(LINK) -o $@ $(WINBINDD_OBJ) $(LIBS) +#bin/winbindd: $(WINBINDD_OBJ) bin/.dummy +# @echo Linking $@ +# @$(LINK) -o $@ $(WINBINDD_OBJ) $(LIBS) -nsswitch/libnss_winbind.so: $(WINBIND_NSS_PICOBJS) - @echo "Linking $@" - @$(LINK) -shared -o $@ $(WINBIND_NSS_PICOBJS) +#nsswitch/libnss_winbind.so: $(WINBIND_NSS_PICOBJS) +# @echo "Linking $@" +# @$(LINK) -shared -o $@ $(WINBIND_NSS_PICOBJS) -nsswitch/pam_winbind.so: $(PAM_WINBIND_OBJ) bin/.dummy - @echo Linking $@ - @$(LINK) -shared -o $@ $(PAM_WINBIND_OBJ) +#nsswitch/pam_winbind.so: $(PAM_WINBIND_OBJ) bin/.dummy +# @echo Linking $@ +# @$(LINK) -shared -o $@ $(PAM_WINBIND_OBJ) -bin/wbinfo: $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) $(NOPROTO_OBJ) $(UBIQX_OBJ) bin/.dummy - @echo Linking $@ - @$(LINK) -o $@ $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) $(NOPROTO_OBJ) \ - $(UBIQX_OBJ) $(LIBS) +#bin/wbinfo: $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) $(NOPROTO_OBJ) $(UBIQX_OBJ) bin/.dummy +# @echo Linking $@ +# @$(LINK) -o $@ $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) $(NOPROTO_OBJ) \ +# $(UBIQX_OBJ) $(LIBS) + +#nsswitch: nsswitch/libnss_wins.so nsswitch/pam_winbind.so \ +# nsswitch/libnss_winbind.so bin/wbinfo -nsswitch: nsswitch/libnss_wins.so nsswitch/pam_winbind.so \ - nsswitch/libnss_winbind.so bin/wbinfo +bin/winbindd nsswitch/libnss_winbind.so nsswitch/pam_winbind.so bin/wbinfo nsswitch: + @echo The winbind code in this branch is not compilable. Please use + @echo the version in HEAD CVS instead. install: installbin installman installscripts installcp installswat diff --git a/source/acconfig.h b/source/acconfig.h index d550a2c4f46..f2b812409fe 100644 --- a/source/acconfig.h +++ b/source/acconfig.h @@ -1,5 +1,6 @@ #undef HAVE_VOLATILE #undef HAVE_BROKEN_READDIR +#undef HAVE_C99_VSNPRINTF #undef HAVE_ERRNO_DECL #undef HAVE_LONGLONG #undef HAVE_OFF64_T @@ -7,6 +8,7 @@ #undef HAVE_UNSIGNED_CHAR #undef HAVE_UTIMBUF #undef HAVE_SIG_ATOMIC_T_TYPE +#undef HAVE_SOCKLEN_T_TYPE #undef ssize_t #undef ino_t #undef ssize_t @@ -61,6 +63,7 @@ #undef WITH_NISPLUS #undef WITH_TDBPWD #undef WITH_PAM +#undef WITH_PAM_SMBPASS #undef WITH_NISPLUS_HOME #undef WITH_AUTOMOUNT #undef WITH_SMBMOUNT @@ -144,6 +147,10 @@ #undef HAVE_UNIXWARE_ACLS #undef HAVE_SOLARIS_ACLS #undef HAVE_IRIX_ACLS -#undef HAVE_XFS_ACLS #undef HAVE_AIX_ACLS #undef HAVE_NO_ACLS +#undef HAVE_LIBPAM +#undef HAVE_ASPRINTF_DECL +#undef HAVE_VASPRINTF_DECL +#undef HAVE_SNPRINTF_DECL +#undef HAVE_VSNPRINTF_DECL diff --git a/source/aclocal.m4 b/source/aclocal.m4 index 9a7145402a9..13788f99bea 100644 --- a/source/aclocal.m4 +++ b/source/aclocal.m4 @@ -49,6 +49,20 @@ fi rm -f conftest* ])]) +dnl see if a declaration exists for a function or variable +dnl defines HAVE_function_DECL if it exists +dnl AC_HAVE_DECL(var, includes) +AC_DEFUN(AC_HAVE_DECL, +[ + AC_CACHE_CHECK([for $1 declaration],ac_cv_have_$1_decl,[ + AC_TRY_COMPILE([$2],[int i = (int)$1], + ac_cv_have_$1_decl=yes,ac_cv_have_$1_decl=no)]) + if test x"$ac_cv_have_$1_decl" = x"yes"; then + AC_DEFINE([HAVE_]translit([$1], [a-z], [A-Z])[_DECL]) + fi +]) + + dnl check for a function in a library, but don't dnl keep adding the same library to the LIBS variable. dnl AC_LIBTESTFUNC(lib,func) diff --git a/source/auth/pampass.c b/source/auth/pampass.c index e6de54dfe69..53d2a062fdd 100644 --- a/source/auth/pampass.c +++ b/source/auth/pampass.c @@ -5,6 +5,7 @@ Copyright (C) Andrew Tridgell 1992-2001 Copyright (C) John H Terpsta 1999-2001 Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jeremy Allison 2001 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 @@ -43,65 +44,106 @@ extern int DEBUGLEVEL; #include <security/pam_appl.h> /* - * Static variables used to communicate between the conversation function - * and the server_login function + * Structure used to communicate between the conversation function + * and the server_login/change password functions. */ -static char *PAM_username; -static char *PAM_password; +struct smb_pam_userdata { + char *PAM_username; + char *PAM_password; + char *PAM_newpassword; +}; + +typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr); /* * Macros to help make life easy */ #define COPY_STRING(s) (s) ? strdup(s) : NULL -/* - * PAM error handler. - */ -static BOOL pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg, int dbglvl) +/******************************************************************* + PAM error handler. + *********************************************************************/ + +static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg, int dbglvl) { - if( pam_error != PAM_SUCCESS) - { - DEBUG(dbglvl, ("PAM: %s : %s\n", msg, pam_strerror(pamh, pam_error))); + if( pam_error != PAM_SUCCESS) { + DEBUG(dbglvl, ("smb_pam_error_handler: PAM: %s : %s\n", + msg, pam_strerror(pamh, pam_error))); + return False; } return True; } +/******************************************************************* + This function is a sanity check, to make sure that we NEVER report + failure as sucess. +*********************************************************************/ + +static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error, + char *msg, int dbglvl, uint32 *nt_status) +{ + if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl)) + return True; + + if (*nt_status == NT_STATUS_NOPROBLEMO) { + /* Complain LOUDLY */ + DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \ +error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE")); + *nt_status = NT_STATUS_LOGON_FAILURE; + } + return False; +} + /* * PAM conversation function * Here we assume (for now, at least) that echo on means login name, and * echo off means password. */ -static int PAM_conv(int num_msg, +static int smb_pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int replies = 0; struct pam_response *reply = NULL; + struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr; + + *resp = NULL; + + if (num_msg <= 0) + return PAM_CONV_ERR; + + /* + * Apparantly HPUX has a buggy PAM that doesn't support the + * appdata_ptr. Fail if this is the case. JRA. + */ + + if (udp == NULL) { + DEBUG(0,("smb_pam_conv: PAM on this system is broken - appdata_ptr == NULL !\n")); + return PAM_CONV_ERR; + } reply = malloc(sizeof(struct pam_response) * num_msg); if (!reply) return PAM_CONV_ERR; - for (replies = 0; replies < num_msg; replies++) - { - switch (msg[replies]->msg_style) - { + memset(reply, '\0', sizeof(struct pam_response) * num_msg); + + for (replies = 0; replies < num_msg; replies++) { + switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_ON: reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = - COPY_STRING(PAM_username); + reply[replies].resp = COPY_STRING(udp->PAM_username); /* PAM frees resp */ break; case PAM_PROMPT_ECHO_OFF: reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = - COPY_STRING(PAM_password); + reply[replies].resp = COPY_STRING(udp->PAM_password); /* PAM frees resp */ break; @@ -125,291 +167,712 @@ static int PAM_conv(int num_msg, return PAM_SUCCESS; } -static struct pam_conv PAM_conversation = { - &PAM_conv, - NULL +/* + * PAM password change conversation function + * Here we assume (for now, at least) that echo on means login name, and + * echo off means password. + */ + +static void special_char_sub(char *buf) +{ + all_string_sub(buf, "\\n", "", 0); + all_string_sub(buf, "\\r", "", 0); + all_string_sub(buf, "\\s", " ", 0); + all_string_sub(buf, "\\t", "\t", 0); +} + +static void pwd_sub(char *buf, char *username, char *oldpass, char *newpass) +{ + pstring_sub(buf, "%u", username); + all_string_sub(buf, "%o", oldpass, sizeof(fstring)); + all_string_sub(buf, "%n", newpass, sizeof(fstring)); +} + + +struct chat_struct { + struct chat_struct *next, *prev; + fstring prompt; + fstring reply; }; +/************************************************************** + Create a linked list containing chat data. +***************************************************************/ + +static struct chat_struct *make_pw_chat(char *p) +{ + fstring prompt; + fstring reply; + struct chat_struct *list = NULL; + struct chat_struct *t; + struct chat_struct *tmp; + + while (1) { + t = (struct chat_struct *)malloc(sizeof(*t)); + if (!t) { + DEBUG(0,("make_pw_chat: malloc failed!\n")); + return NULL; + } + + ZERO_STRUCTP(t); + + DLIST_ADD_END(list, t, tmp); + + if (!next_token(&p, prompt, NULL, sizeof(fstring))) + break; + + if (strequal(prompt,".")) + fstrcpy(prompt,"*"); + + special_char_sub(prompt); + fstrcpy(t->prompt, prompt); + + if (!next_token(&p, reply, NULL, sizeof(fstring))) + break; + + if (strequal(reply,".")) + fstrcpy(reply,""); + + special_char_sub(reply); + fstrcpy(t->reply, reply); + + } + return list; +} + +static void free_pw_chat(struct chat_struct *list) +{ + while (list) { + struct chat_struct *old_head = list; + DLIST_REMOVE(list, list); + free(old_head); + } +} + +static int smb_pam_passchange_conv(int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) +{ + int replies = 0; + struct pam_response *reply = NULL; + fstring current_prompt; + fstring current_reply; + struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr; + struct chat_struct *pw_chat= make_pw_chat(lp_passwd_chat()); + struct chat_struct *t; + BOOL found; + *resp = NULL; + + DEBUG(10,("smb_pam_passchange_conv: starting converstation for %d messages\n", num_msg)); + + if (num_msg <= 0) + return PAM_CONV_ERR; + + if (pw_chat == NULL) + return PAM_CONV_ERR; + + /* + * Apparantly HPUX has a buggy PAM that doesn't support the + * appdata_ptr. Fail if this is the case. JRA. + */ + + if (udp == NULL) { + DEBUG(0,("smb_pam_passchange_conv: PAM on this system is broken - appdata_ptr == NULL !\n")); + free_pw_chat(pw_chat); + return PAM_CONV_ERR; + } + + reply = malloc(sizeof(struct pam_response) * num_msg); + if (!reply) { + DEBUG(0,("smb_pam_passchange_conv: malloc for reply failed!\n")); + free_pw_chat(pw_chat); + return PAM_CONV_ERR; + } + + for (replies = 0; replies < num_msg; replies++) { + found = False; + DEBUG(10,("smb_pam_passchange_conv: Processing message %d\n", replies)); + switch (msg[replies]->msg_style) { + case PAM_PROMPT_ECHO_ON: + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: PAM said: %s\n", msg[replies]->msg)); + fstrcpy(current_prompt, msg[replies]->msg); + strlower(current_prompt); + for (t=pw_chat; t; t=t->next) { + if (ms_fnmatch(t->prompt, current_prompt) == 0) { + fstrcpy(current_reply, t->reply); + pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword); + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We sent: %s\n", current_reply)); + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = COPY_STRING(current_reply); + found = True; + break; + } + } + /* PAM frees resp */ + if (!found) { + DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg)); + free_pw_chat(pw_chat); + free(reply); + reply = NULL; + return PAM_CONV_ERR; + } + break; + + case PAM_PROMPT_ECHO_OFF: + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: PAM said: %s\n", msg[replies]->msg)); + fstrcpy(current_prompt, msg[replies]->msg); + strlower(current_prompt); + for (t=pw_chat; t; t=t->next) { + if (ms_fnmatch(t->prompt, current_prompt) == 0) { + fstrcpy(current_reply, t->reply); + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We sent: %s\n", current_reply)); + pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword); + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = COPY_STRING(current_reply); +#ifdef DEBUG_PASSWORD + DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actualy sent: %s\n", current_reply)); +#endif + found = True; + break; + } + } + /* PAM frees resp */ + + if (!found) { + DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg)); + free_pw_chat(pw_chat); + free(reply); + reply = NULL; + return PAM_CONV_ERR; + } + break; + + case PAM_TEXT_INFO: + /* fall through */ + + case PAM_ERROR_MSG: + /* ignore it... */ + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = NULL; + break; + + default: + /* Must be an error of some sort... */ + free_pw_chat(pw_chat); + free(reply); + reply = NULL; + return PAM_CONV_ERR; + } + } + + free_pw_chat(pw_chat); + if (reply) + *resp = reply; + return PAM_SUCCESS; +} + +/*************************************************************************** + Free up a malloced pam_conv struct. +****************************************************************************/ + +static void smb_free_pam_conv(struct pam_conv *pconv) +{ + if (pconv) + safe_free(pconv->appdata_ptr); + + safe_free(pconv); +} + +/*************************************************************************** + Allocate a pam_conv struct. +****************************************************************************/ + +static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, char *user, + char *passwd, char *newpass) +{ + struct pam_conv *pconv = (struct pam_conv *)malloc(sizeof(struct pam_conv)); + struct smb_pam_userdata *udp = (struct smb_pam_userdata *)malloc(sizeof(struct smb_pam_userdata)); + + if (pconv == NULL || udp == NULL) { + safe_free(pconv); + safe_free(udp); + return NULL; + } + + udp->PAM_username = user; + udp->PAM_password = passwd; + udp->PAM_newpassword = newpass; + + pconv->conv = smb_pam_conv_fnptr; + pconv->appdata_ptr = (void *)udp; + return pconv; +} + /* * PAM Closing out cleanup handler */ -static BOOL proc_pam_end(pam_handle_t *pamh) + +static BOOL smb_pam_end(pam_handle_t *pamh, struct pam_conv *smb_pam_conv_ptr) { - int pam_error; + int pam_error; + + smb_free_pam_conv(smb_pam_conv_ptr); - if( pamh != NULL ) - { + if( pamh != NULL ) { pam_error = pam_end(pamh, 0); - if(pam_error_handler(pamh, pam_error, "End Cleanup Failed", 2) == True) { - DEBUG(4, ("PAM: PAM_END OK.\n")); - return True; + if(smb_pam_error_handler(pamh, pam_error, "End Cleanup Failed", 2) == True) { + DEBUG(4, ("smb_pam_end: PAM: PAM_END OK.\n")); + return True; } - } - DEBUG(2,("PAM: not initialised")); - return False; + } + DEBUG(2,("smb_pam_end: PAM: not initialised")); + return False; } /* * Start PAM authentication for specified account */ -static BOOL proc_pam_start(pam_handle_t **pamh, char *user) + +static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct pam_conv *pconv) { - int pam_error; - char * rhost; + int pam_error; - DEBUG(4,("PAM: Init user: %s\n", user)); + *pamh = (pam_handle_t *)NULL; - pam_error = pam_start("samba", user, &PAM_conversation, pamh); - if( !pam_error_handler(*pamh, pam_error, "Init Failed", 0)) { - proc_pam_end(*pamh); - return False; - } + DEBUG(4,("smb_pam_start: PAM: Init user: %s\n", user)); - rhost = client_name(); - if (strcmp(rhost,"UNKNOWN") == 0) - rhost = client_addr(); + pam_error = pam_start("samba", user, pconv, pamh); + if( !smb_pam_error_handler(*pamh, pam_error, "Init Failed", 0)) { + *pamh = (pam_handle_t *)NULL; + return False; + } + + if (rhost == NULL) { + rhost = client_name(); + if (strequal(rhost,"UNKNOWN")) + rhost = client_addr(); + } #ifdef PAM_RHOST - DEBUG(4,("PAM: setting rhost to: %s\n", rhost)); - pam_error = pam_set_item(*pamh, PAM_RHOST, rhost); - if(!pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) { - proc_pam_end(*pamh); - return False; - } + DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", rhost)); + pam_error = pam_set_item(*pamh, PAM_RHOST, rhost); + if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) { + smb_pam_end(*pamh, pconv); + *pamh = (pam_handle_t *)NULL; + return False; + } #endif #ifdef PAM_TTY - DEBUG(4,("PAM: setting tty\n")); - pam_error = pam_set_item(*pamh, PAM_TTY, "samba"); - if (!pam_error_handler(*pamh, pam_error, "set tty failed", 0)) { - proc_pam_end(*pamh); - return False; - } + DEBUG(4,("smb_pam_start: PAM: setting tty\n")); + pam_error = pam_set_item(*pamh, PAM_TTY, "samba"); + if (!smb_pam_error_handler(*pamh, pam_error, "set tty failed", 0)) { + smb_pam_end(*pamh, pconv); + *pamh = (pam_handle_t *)NULL; + return False; + } #endif - DEBUG(4,("PAM: Init passed for user: %s\n", user)); - return True; + DEBUG(4,("smb_pam_start: PAM: Init passed for user: %s\n", user)); + return True; } /* * PAM Authentication Handler */ -static BOOL pam_auth(pam_handle_t *pamh, char *user, char *password) +static uint32 smb_pam_auth(pam_handle_t *pamh, char *user) { int pam_error; + uint32 nt_status = NT_STATUS_LOGON_FAILURE; /* * To enable debugging set in /etc/pam.d/samba: * auth required /lib/security/pam_pwdb.so nullok shadow audit */ - DEBUG(4,("PAM: Authenticate User: %s\n", user)); - pam_error = pam_authenticate(pamh, PAM_SILENT); /* Can we authenticate user? */ + DEBUG(4,("smb_pam_auth: PAM: Authenticate User: %s\n", user)); + pam_error = pam_authenticate(pamh, PAM_SILENT | lp_null_passwords() ? 0 : PAM_DISALLOW_NULL_AUTHTOK); switch( pam_error ){ case PAM_AUTH_ERR: - DEBUG(2, ("PAM: Athentication Error\n")); + DEBUG(2, ("smb_pam_auth: PAM: Athentication Error for user %s\n", user)); + nt_status = NT_STATUS_WRONG_PASSWORD; break; case PAM_CRED_INSUFFICIENT: - DEBUG(2, ("PAM: Insufficient Credentials\n")); + DEBUG(2, ("smb_pam_auth: PAM: Insufficient Credentials for user %s\n", user)); + nt_status = NT_STATUS_INSUFFICIENT_LOGON_INFO; break; case PAM_AUTHINFO_UNAVAIL: - DEBUG(2, ("PAM: Authentication Information Unavailable\n")); + DEBUG(2, ("smb_pam_auth: PAM: Authentication Information Unavailable for user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; break; case PAM_USER_UNKNOWN: - DEBUG(2, ("PAM: Username NOT known to Authentication system\n")); + DEBUG(2, ("smb_pam_auth: PAM: Username %s NOT known to Authentication system\n", user)); + nt_status = NT_STATUS_NO_SUCH_USER; break; case PAM_MAXTRIES: - DEBUG(2, ("PAM: One or more authentication modules reports user limit exceeeded\n")); + DEBUG(2, ("smb_pam_auth: PAM: One or more authentication modules reports user limit for user %s exceeeded\n", user)); + nt_status = NT_STATUS_REMOTE_SESSION_LIMIT; break; case PAM_ABORT: - DEBUG(0, ("PAM: One or more PAM modules failed to load\n")); + DEBUG(0, ("smb_pam_auth: PAM: One or more PAM modules failed to load for user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; + break; + case PAM_SUCCESS: + DEBUG(4, ("smb_pam_auth: PAM: User %s Authenticated OK\n", user)); + nt_status = NT_STATUS_NOPROBLEMO; break; - case PAM_SUCCESS: - DEBUG(4, ("PAM: User %s Authenticated OK\n", user)); - break; default: - DEBUG(0, ("PAM: UNKNOWN ERROR while authenticating user %s\n", user)); - } - if(!pam_error_handler(pamh, pam_error, "Authentication Failure", 2)) { - proc_pam_end(pamh); - return False; + DEBUG(0, ("smb_pam_auth: PAM: UNKNOWN ERROR while authenticating user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; + break; } - /* If this point is reached, the user has been authenticated. */ - return (True); + + smb_pam_nt_status_error_handler(pamh, pam_error, "Authentication Failure", 2, &nt_status); + return nt_status; } /* * PAM Account Handler */ -static BOOL pam_account(pam_handle_t *pamh, char * user, char * password) +static uint32 smb_pam_account(pam_handle_t *pamh, char * user) { int pam_error; + uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED; - DEBUG(4,("PAM: Account Management for User: %s\n", user)); + DEBUG(4,("smb_pam_account: PAM: Account Management for User: %s\n", user)); pam_error = pam_acct_mgmt(pamh, PAM_SILENT); /* Is user account enabled? */ switch( pam_error ) { case PAM_AUTHTOK_EXPIRED: - DEBUG(2, ("PAM: User is valid but password is expired\n")); + DEBUG(2, ("smb_pam_account: PAM: User %s is valid but password is expired\n", user)); + nt_status = NT_STATUS_PASSWORD_EXPIRED; break; case PAM_ACCT_EXPIRED: - DEBUG(2, ("PAM: User no longer permitted to access system\n")); + DEBUG(2, ("smb_pam_account: PAM: User %s no longer permitted to access system\n", user)); + nt_status = NT_STATUS_ACCOUNT_EXPIRED; break; case PAM_AUTH_ERR: - DEBUG(2, ("PAM: There was an authentication error\n")); + DEBUG(2, ("smb_pam_account: PAM: There was an authentication error for user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; break; case PAM_PERM_DENIED: - DEBUG(0, ("PAM: User is NOT permitted to access system at this time\n")); + DEBUG(0, ("smb_pam_account: PAM: User %s is NOT permitted to access system at this time\n", user)); + nt_status = NT_STATUS_ACCOUNT_RESTRICTION; break; case PAM_USER_UNKNOWN: - DEBUG(0, ("PAM: User \"%s\" is NOT known to account management\n", user)); + DEBUG(0, ("smb_pam_account: PAM: User \"%s\" is NOT known to account management\n", user)); + nt_status = NT_STATUS_NO_SUCH_USER; + break; + case PAM_SUCCESS: + DEBUG(4, ("smb_pam_account: PAM: Account OK for User: %s\n", user)); + nt_status = NT_STATUS_NOPROBLEMO; break; - case PAM_SUCCESS: - DEBUG(4, ("PAM: Account OK for User: %s\n", user)); - break; default: - DEBUG(0, ("PAM: UNKNOWN ERROR for User: %s\n", user)); - } - if(!pam_error_handler(pamh, pam_error, "Account Check Failed", 2)) { - proc_pam_end(pamh); - return False; + nt_status = NT_STATUS_ACCOUNT_DISABLED; + DEBUG(0, ("smb_pam_account: PAM: UNKNOWN PAM ERROR (%d) during Account Management for User: %s\n", pam_error, user)); + break; } + smb_pam_nt_status_error_handler(pamh, pam_error, "Account Check Failed", 2, &nt_status); + return nt_status; +} + +/* + * PAM Credential Setting + */ + +static uint32 smb_pam_setcred(pam_handle_t *pamh, char * user) +{ + int pam_error; + uint32 nt_status = NT_STATUS_NO_TOKEN; + /* * This will allow samba to aquire a kerberos token. And, when * exporting an AFS cell, be able to /write/ to this cell. */ - DEBUG(4,("PAM: Account Management SetCredentials for User: %s\n", user)); + DEBUG(4,("PAM: Account Management SetCredentials for User: %s\n", user)); pam_error = pam_setcred(pamh, (PAM_ESTABLISH_CRED|PAM_SILENT)); - if(!pam_error_handler(pamh, pam_error, "Set Credential Failure", 2)) { - proc_pam_end(pamh); + switch( pam_error ) { + case PAM_CRED_UNAVAIL: + DEBUG(0, ("smb_pam_setcred: PAM: Credentials not found for user:%s\n", user )); + nt_status = NT_STATUS_NO_TOKEN; + break; + case PAM_CRED_EXPIRED: + DEBUG(0, ("smb_pam_setcred: PAM: Credentials for user: \"%s\" EXPIRED!\n", user )); + nt_status = NT_STATUS_PASSWORD_EXPIRED; + break; + case PAM_USER_UNKNOWN: + DEBUG(0, ("smb_pam_setcred: PAM: User: \"%s\" is NOT known so can not set credentials!\n", user )); + nt_status = NT_STATUS_NO_SUCH_USER; + break; + case PAM_CRED_ERR: + DEBUG(0, ("smb_pam_setcred: PAM: Unknown setcredentials error - unable to set credentials for %s\n", user )); + nt_status = NT_STATUS_LOGON_FAILURE; + break; + case PAM_SUCCESS: + DEBUG(4, ("smb_pam_setcred: PAM: SetCredentials OK for User: %s\n", user)); + nt_status = NT_STATUS_NOPROBLEMO; + break; + default: + DEBUG(0, ("smb_pam_setcred: PAM: UNKNOWN PAM ERROR (%d) during SetCredentials for User: %s\n", pam_error, user)); + nt_status = NT_STATUS_NO_TOKEN; + break; + } + + smb_pam_nt_status_error_handler(pamh, pam_error, "Set Credential Failure", 2, &nt_status); + return nt_status; +} + +/* + * PAM Internal Session Handler + */ +static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag) +{ + int pam_error; + +#ifdef PAM_TTY + DEBUG(4,("smb_internal_pam_session: PAM: tty set to: %s\n", tty)); + pam_error = pam_set_item(pamh, PAM_TTY, tty); + if (!smb_pam_error_handler(pamh, pam_error, "set tty failed", 0)) return False; +#endif + + if (flag) { + pam_error = pam_open_session(pamh, PAM_SILENT); + if (!smb_pam_error_handler(pamh, pam_error, "session setup failed", 0)) + return False; + } else { + pam_setcred(pamh, (PAM_DELETE_CRED|PAM_SILENT)); /* We don't care if this fails */ + pam_error = pam_close_session(pamh, PAM_SILENT); /* This will probably pick up the error anyway */ + if (!smb_pam_error_handler(pamh, pam_error, "session close failed", 0)) + return False; } - - /* If this point is reached, the user has been authenticated. */ return (True); } - /* - * PAM Internal Session Handler + * Internal PAM Password Changer. */ -static BOOL proc_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag) + +static BOOL smb_pam_chauthtok(pam_handle_t *pamh, char * user) { - int pam_error; + int pam_error; - PAM_password = NULL; - PAM_username = user; + DEBUG(4,("smb_pam_chauthtok: PAM: Password Change for User: %s\n", user)); -#ifdef PAM_TTY - DEBUG(4,("PAM: tty set to: %s\n", tty)); - pam_error = pam_set_item(pamh, PAM_TTY, tty); - if (!pam_error_handler(pamh, pam_error, "set tty failed", 0)) { - proc_pam_end(pamh); - return False; - } + pam_error = pam_chauthtok(pamh, PAM_SILENT); /* Change Password */ + + switch( pam_error ) { + case PAM_AUTHTOK_ERR: + DEBUG(2, ("PAM: unable to obtain the new authentication token - is password to weak?\n")); + break; + + /* This doesn't seem to be defined on Solaris. JRA */ +#ifdef PAM_AUTHTOK_RECOVER_ERR + case PAM_AUTHTOK_RECOVER_ERR: + DEBUG(2, ("PAM: unable to obtain the old authentication token - was the old password wrong?.\n")); + break; #endif - if (flag) { - pam_error = pam_open_session(pamh, PAM_SILENT); - if (!pam_error_handler(pamh, pam_error, "session setup failed", 0)) { - proc_pam_end(pamh); - return False; - } - } - else - { - pam_error = pam_close_session(pamh, PAM_SILENT); - if (!pam_error_handler(pamh, pam_error, "session close failed", 0)) { - proc_pam_end(pamh); - return False; - } - } - return (True); + case PAM_AUTHTOK_LOCK_BUSY: + DEBUG(2, ("PAM: unable to change the authentication token since it is currently locked.\n")); + break; + case PAM_AUTHTOK_DISABLE_AGING: + DEBUG(2, ("PAM: Authentication token aging has been disabled.\n")); + break; + case PAM_PERM_DENIED: + DEBUG(0, ("PAM: Permission denied.\n")); + break; + case PAM_TRY_AGAIN: + DEBUG(0, ("PAM: Could not update all authentication token(s). No authentication tokens were updated.\n")); + break; + case PAM_USER_UNKNOWN: + DEBUG(0, ("PAM: User not known to PAM\n")); + break; + case PAM_SUCCESS: + DEBUG(4, ("PAM: Account OK for User: %s\n", user)); + break; + default: + DEBUG(0, ("PAM: UNKNOWN PAM ERROR (%d) for User: %s\n", pam_error, user)); + } + + if(!smb_pam_error_handler(pamh, pam_error, "Password Change Failed", 2)) { + return False; + } + + /* If this point is reached, the password has changed. */ + return True; } /* * PAM Externally accessible Session handler */ -BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty) + +BOOL smb_pam_claim_session(char *user, char *tty, char *rhost) { pam_handle_t *pamh = NULL; - char * user; + struct pam_conv *pconv = NULL; + + /* Ignore PAM if told to. */ + + if (!lp_obey_pam_restrictions()) + return True; - user = malloc(strlen(conn->user)+1); - if ( user == NULL ) - { - DEBUG(0, ("PAM: PAM_session Malloc Failed!\n")); + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL) return False; - } - /* This is freed by PAM */ - StrnCpy(user, conn->user, strlen(conn->user)+1); + if (!smb_pam_start(&pamh, user, rhost, pconv)) + return False; - if (!proc_pam_start(&pamh, user)) - { - proc_pam_end(pamh); - return False; + if (!smb_internal_pam_session(pamh, user, tty, True)) { + smb_pam_end(pamh, pconv); + return False; } - if (proc_pam_session(pamh, user, tty, flag)) - { - return proc_pam_end(pamh); - } - else - { - proc_pam_end(pamh); - return False; + return smb_pam_end(pamh, pconv); +} + +/* + * PAM Externally accessible Session handler + */ + +BOOL smb_pam_close_session(char *user, char *tty, char *rhost) +{ + pam_handle_t *pamh = NULL; + struct pam_conv *pconv = NULL; + + /* Ignore PAM if told to. */ + + if (!lp_obey_pam_restrictions()) + return True; + + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL) + return False; + + if (!smb_pam_start(&pamh, user, rhost, pconv)) + return False; + + if (!smb_internal_pam_session(pamh, user, tty, False)) { + smb_pam_end(pamh, pconv); + return False; } + + return smb_pam_end(pamh, pconv); } /* * PAM Externally accessible Account handler */ -BOOL pam_accountcheck(char * user) + +uint32 smb_pam_accountcheck(char * user) { + uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED; pam_handle_t *pamh = NULL; + struct pam_conv *pconv = NULL; - PAM_username = user; - PAM_password = NULL; + /* Ignore PAM if told to. */ - if( proc_pam_start(&pamh, user)) - { - if ( pam_account(pamh, user, NULL)) - { - return( proc_pam_end(pamh)); - } - } - DEBUG(0, ("PAM: Account Validation Failed - Rejecting User!\n")); - return( False ); + if (!lp_obey_pam_restrictions()) + return NT_STATUS_NOPROBLEMO; + + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL) + return False; + + if (!smb_pam_start(&pamh, user, NULL, pconv)) + return NT_STATUS_ACCOUNT_DISABLED; + + if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO) + DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user)); + + smb_pam_end(pamh, pconv); + return nt_status; } /* * PAM Password Validation Suite */ -BOOL pam_passcheck(char * user, char * password) + +uint32 smb_pam_passcheck(char * user, char * password) { pam_handle_t *pamh = NULL; + uint32 nt_status = NT_STATUS_LOGON_FAILURE; + struct pam_conv *pconv = NULL; - PAM_username = user; - PAM_password = password; + /* + * Note we can't ignore PAM here as this is the only + * way of doing auths on plaintext passwords when + * compiled --with-pam. + */ - if( proc_pam_start(&pamh, user)) - { - if ( pam_auth(pamh, user, password)) - { - if ( pam_account(pamh, user, password)) - { - return( proc_pam_end(pamh)); - } - } + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, password, NULL)) == NULL) + return NT_STATUS_LOGON_FAILURE; + + if (!smb_pam_start(&pamh, user, NULL, pconv)) + return NT_STATUS_LOGON_FAILURE; + + if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_NOPROBLEMO) { + DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user)); + smb_pam_end(pamh, pconv); + return nt_status; + } + + if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO) { + DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user)); + smb_pam_end(pamh, pconv); + return nt_status; + } + + if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_NOPROBLEMO) { + DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user)); + smb_pam_end(pamh, pconv); + return nt_status; + } + + smb_pam_end(pamh, pconv); + return nt_status; +} + +/* + * PAM Password Change Suite + */ + +BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword) +{ + /* Appropriate quantities of root should be obtained BEFORE calling this function */ + struct pam_conv *pconv = NULL; + pam_handle_t *pamh = NULL; + + if ((pconv = smb_setup_pam_conv(smb_pam_passchange_conv, user, oldpassword, newpassword)) == NULL) + return False; + + if(!smb_pam_start(&pamh, user, NULL, pconv)) + return False; + + if (!smb_pam_chauthtok(pamh, user)) { + DEBUG(0, ("smb_pam_passchange: PAM: Password Change Failed for user %s!\n", user)); + smb_pam_end(pamh, pconv); + return False; } - DEBUG(0, ("PAM: System Validation Failed - Rejecting User!\n")); - return( False ); + + return smb_pam_end(pamh, pconv); } #else - /* Do *NOT* make this function static. Doing so breaks the compile on gcc */ +/* If PAM not used, no PAM restrictions on accounts. */ + uint32 smb_pam_accountcheck(char * user) +{ + return NT_STATUS_NOPROBLEMO; +} - void pampass_dummy_function( void ) { } /*This stops compiler complaints */ +/* If PAM not used, also no PAM restrictions on sessions. */ + BOOL smb_pam_claim_session(char *user, char *tty, char *rhost) +{ + return True; +} +/* If PAM not used, also no PAM restrictions on sessions. */ + BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost) +{ + return True; +} #endif /* WITH_PAM */ diff --git a/source/auth/pass_check.c b/source/auth/pass_check.c index 236465bc903..9424189b236 100644 --- a/source/auth/pass_check.c +++ b/source/auth/pass_check.c @@ -599,7 +599,7 @@ static BOOL password_check(char *password) { #ifdef WITH_PAM - return (pam_passcheck(this_user, password)); + return (smb_pam_passcheck(this_user, password) == NT_STATUS_NOPROBLEMO); #endif /* WITH_PAM */ #ifdef WITH_AFS @@ -681,12 +681,13 @@ the function pointer fn() points to a function to call when a successful match is found and is used to update the encrypted password file return True on correct match, False otherwise ****************************************************************************/ + BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd, BOOL (*fn) (char *, char *)) { pstring pass2; int level = lp_passwordlevel(); - struct passwd *pass; + struct passwd *pass = NULL; if (password) password[pwlen] = 0; @@ -708,8 +709,20 @@ BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd, pass = Get_Pwnam(user, True); } +#ifdef WITH_PAM + + /* + * If we're using PAM we want to short-circuit all the + * checks below and dive straight into the PAM code. + */ + + fstrcpy(this_user, user); + + DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen)); + +#else /* Not using PAM */ - DEBUG(4, ("Checking password for user %s (l=%d)\n", user, pwlen)); + DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen)); if (!pass) { DEBUG(3, ("Couldn't find user %s\n", user)); @@ -802,6 +815,8 @@ BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd, } } +#endif /* WITH_PAM */ + /* try it as it came to us */ if (password_check(password)) { if (fn) diff --git a/source/client/client.c b/source/client/client.c index be2e6238c3b..4969156f083 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -473,7 +473,7 @@ static int do_list_queue_empty(void) /**************************************************************************** a helper for do_list ****************************************************************************/ -static void do_list_helper(file_info *f, const char *mask) +static void do_list_helper(file_info *f, const char *mask, void *state) { if (f->mode & aDIR) { if (do_list_dirs && do_this_one(f)) { @@ -537,7 +537,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, */ pstring head; pstrcpy(head, do_list_queue_head()); - cli_list(cli, head, attribute, do_list_helper); + cli_list(cli, head, attribute, do_list_helper, NULL); remove_do_list_queue_head(); if ((! do_list_queue_empty()) && (fn == display_finfo)) { @@ -561,7 +561,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, } else { - if (cli_list(cli, mask, attribute, do_list_helper) == -1) + if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1) { DEBUG(0, ("%s listing %s\n", cli_errstr(cli), mask)); } @@ -1117,27 +1117,50 @@ static void cmd_put(void) do_put(rname,lname); } +/************************************* + File list structure +*************************************/ + +static struct file_list { + struct file_list *prev, *next; + char *file_path; + BOOL isdir; +} *file_list; + +/**************************************************************************** + Free a file_list structure +****************************************************************************/ + +static void free_file_list (struct file_list * list) +{ + struct file_list *tmp; + + while (list) + { + tmp = list; + DLIST_REMOVE(list, list); + if (tmp->file_path) free(tmp->file_path); + free(tmp); + } +} /**************************************************************************** seek in a directory/file list until you get something that doesn't start with the specified name ****************************************************************************/ -static BOOL seek_list(FILE *f,char *name) +static BOOL seek_list(struct file_list *list, char *name) { - pstring s; - while (!feof(f)) { - if (!fgets(s,sizeof(s),f)) return(False); - trim_string(s,"./","\n"); - if (strncmp(s,name,strlen(name)) != 0) { - pstrcpy(name,s); + while (list) { + trim_string(list->file_path,"./","\n"); + if (strncmp(list->file_path, name, strlen(name)) != 0) { return(True); } + list = list->next; } return(False); } - /**************************************************************************** set the file selection mask ****************************************************************************/ @@ -1147,90 +1170,146 @@ static void cmd_select(void) next_token(NULL,fileselection,NULL,sizeof(fileselection)); } +/**************************************************************************** + Recursive file matching function act as find + match must be always set to True when calling this function +****************************************************************************/ +static int file_find(struct file_list **list, const char *directory, + const char *expression, BOOL match) +{ + DIR *dir; + struct file_list *entry; + struct stat statbuf; + int ret; + char *path; + BOOL isdir; + char *dname; + + dir = opendir(directory); + if (!dir) return -1; + + while ((dname = readdirname(dir))) { + if (!strcmp("..", dname)) continue; + if (!strcmp(".", dname)) continue; + + if (asprintf(&path, "%s/%s", directory, dname) <= 0) { + continue; + } + + isdir = False; + if (!match || !ms_fnmatch(expression, dname)) { + if (recurse) { + ret = stat(path, &statbuf); + if (ret == 0) { + if (S_ISDIR(statbuf.st_mode)) { + isdir = True; + ret = file_find(list, path, expression, False); + } + } else { + DEBUG(0,("file_find: cannot stat file %s\n", path)); + } + + if (ret == -1) { + free(path); + closedir(dir); + return -1; + } + } + entry = (struct file_list *) malloc(sizeof (struct file_list)); + if (!entry) { + DEBUG(0,("Out of memory in file_find\n")); + closedir(dir); + return -1; + } + entry->file_path = path; + entry->isdir = isdir; + DLIST_ADD(*list, entry); + } else { + free(path); + } + } + + closedir(dir); + return 0; +} /**************************************************************************** mput some files ****************************************************************************/ static void cmd_mput(void) { - pstring lname; - pstring rname; fstring buf; char *p=buf; while (next_token(NULL,p,NULL,sizeof(buf))) { - SMB_STRUCT_STAT st; - pstring cmd; - pstring tmpname; - FILE *f; - int fd; - - slprintf(tmpname,sizeof(tmpname)-1, "%s/ls.smb.XXXXXX", - tmpdir()); - fd = smb_mkstemp(tmpname); + int ret; + struct file_list *temp_list; + char *quest, *lname, *rname; + + file_list = NULL; - if (fd == -1) { - DEBUG(0,("Failed to create temporary file %s\n", tmpname)); + ret = file_find(&file_list, ".", p, True); + if (ret) { + free_file_list(file_list); continue; } - - if (recurse) - slprintf(cmd,sizeof(pstring)-1, - "find . -name \"%s\" -print > %s",p,tmpname); - else - slprintf(cmd,sizeof(pstring)-1, - "find . -maxdepth 1 -name \"%s\" -print > %s",p,tmpname); - system(cmd); - close(fd); - - f = sys_fopen(tmpname,"r"); - if (!f) continue; - while (!feof(f)) { - pstring quest; + quest = NULL; + lname = NULL; + rname = NULL; + + for (temp_list = file_list; temp_list; + temp_list = temp_list->next) { - if (!fgets(lname,sizeof(lname),f)) break; - trim_string(lname,"./","\n"); - - again1: + if (lname) free(lname); + if (asprintf(&lname, "%s/", temp_list->file_path) <= 0) + continue; + trim_string(lname, "./", "/"); /* check if it's a directory */ - if (directory_exist(lname,&st)) { - if (!recurse) continue; - slprintf(quest,sizeof(pstring)-1, - "Put directory %s? ",lname); - if (prompt && !yesno(quest)) { - pstrcat(lname,"/"); - if (!seek_list(f,lname)) - break; - goto again1; - } - - pstrcpy(rname,cur_dir); - pstrcat(rname,lname); - dos_format(rname); - if (!cli_chkpath(cli, rname) && !do_mkdir(rname)) { - pstrcat(lname,"/"); - if (!seek_list(f,lname)) - break; - goto again1; + if (temp_list->isdir) { + /* if (!recurse) continue; */ + + if (quest) free(quest); + asprintf(&quest, "Put directory %s? ", lname); + if (prompt && !yesno(quest)) { /* No */ + /* Skip the directory */ + lname[strlen(lname)-1] = '/'; + if (!seek_list(temp_list, lname)) + break; + } else { /* Yes */ + if (rname) free(rname); + asprintf(&rname, "%s%s", cur_dir, lname); + dos_format(rname); + if (!cli_chkpath(cli, rname) && + !do_mkdir(rname)) { + DEBUG (0, ("Unable to make dir, skipping...")); + /* Skip the directory */ + lname[strlen(lname)-1] = '/'; + if (!seek_list(temp_list, lname)) + break; + } } continue; } else { - slprintf(quest,sizeof(quest)-1, - "Put file %s? ",lname); - if (prompt && !yesno(quest)) continue; + if (quest) free(quest); + asprintf(&quest,"Put file %s? ", lname); + if (prompt && !yesno(quest)) /* No */ + continue; - pstrcpy(rname,cur_dir); - pstrcat(rname,lname); + /* Yes */ + if (rname) free(rname); + asprintf(&rname, "%s%s", cur_dir, lname); } dos_format(rname); - do_put(rname,lname); + do_put(rname, lname); } - fclose(f); - unlink(tmpname); + free_file_list(file_list); + if (quest) free(quest); + if (lname) free(lname); + if (rname) free(rname); } } @@ -1548,7 +1627,8 @@ static void cmd_lcd(void) /**************************************************************************** list a share name ****************************************************************************/ -static void browse_fn(const char *name, uint32 m, const char *comment) +static void browse_fn(const char *name, uint32 m, + const char *comment, void *state) { fstring typestr; @@ -1581,7 +1661,7 @@ static BOOL browse_host(BOOL sort) printf("\n\tSharename Type Comment\n"); printf("\t--------- ---- -------\n"); - if((ret = cli_RNetShareEnum(cli, browse_fn)) == -1) + if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1) printf("Error returning browse list: %s\n", cli_errstr(cli)); return (ret != -1); @@ -1590,7 +1670,8 @@ static BOOL browse_host(BOOL sort) /**************************************************************************** list a server name ****************************************************************************/ -static void server_fn(const char *name, uint32 m, const char *comment) +static void server_fn(const char *name, uint32 m, + const char *comment, void *state) { printf("\t%-16.16s %s\n", name, comment); } @@ -1605,12 +1686,12 @@ static BOOL list_servers(char *wk_grp) printf("\n\tServer Comment\n"); printf("\t--------- -------\n"); - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn); + cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, NULL); printf("\n\tWorkgroup Master\n"); printf("\t--------- -------\n"); - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn); + cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn, NULL); return True; } @@ -1846,13 +1927,13 @@ static void process_stdin(void) while (1) { fstring tok; - fstring prompt; + fstring the_prompt; char *line; int i; /* display a prompt */ - slprintf(prompt, sizeof(prompt)-1, "smb: %s> ", cur_dir); - line = smb_readline(prompt, readline_callback, completion_fn); + slprintf(the_prompt, sizeof(the_prompt)-1, "smb: %s> ", cur_dir); + line = smb_readline(the_prompt, readline_callback, completion_fn); if (!line) break; diff --git a/source/client/smbspool.c b/source/client/smbspool.c index b0077b73bae..1a17b15b896 100644 --- a/source/client/smbspool.c +++ b/source/client/smbspool.c @@ -115,7 +115,7 @@ static int smb_print(struct cli_state *, char *, FILE *); copies = atoi(argv[4]); /* - * Fine the URI... + * Find the URI... */ if (strncmp(argv[0], "smb://", 6) == 0) @@ -205,11 +205,33 @@ static int smb_print(struct cli_state *, char *, FILE *); load_interfaces(); - if ((cli = smb_connect(workgroup, server, printer, username, password)) == NULL) + do { - perror("ERROR: Unable to connect to SAMBA host"); - return (1); + if ((cli = smb_connect(workgroup, server, printer, username, password)) == NULL) + { + if (getenv("CLASS") == NULL) + { + perror("ERROR: Unable to connect to SAMBA host, will retry in 60 seconds..."); + sleep (60); + } + else + { + perror("ERROR: Unable to connect to SAMBA host, trying next printer..."); + return (1); + } + } } + while (cli == NULL); + + /* + * Now that we are connected to the server, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... Only ignore SIGTERM if we are printing data from + * stdin (otherwise you can't cancel raw jobs...) + */ + + if (argc < 7) + CatchSignal(SIGTERM, SIG_IGN); /* * Queue the job... @@ -279,7 +301,7 @@ smb_connect(char *workgroup, /* I - Workgroup */ if ((c = cli_initialise(NULL)) == NULL) { - fputs("ERROR: cli_initialize() failed...\n", stderr); + fputs("ERROR: cli_initialise() failed...\n", stderr); return (NULL); } @@ -358,7 +380,7 @@ smb_print(struct cli_state *cli, /* I - SMB connection */ */ for (ptr = title; *ptr; ptr ++) - if (!isalnum(*ptr) && !isspace(*ptr)) + if (!isalnum((int)*ptr) && !isspace((int)*ptr)) *ptr = '_'; /* diff --git a/source/codepages/CPISO8859-15.TXT b/source/codepages/CPISO8859-15.TXT index ec643bb3b12..dc23eafeb01 100644 --- a/source/codepages/CPISO8859-15.TXT +++ b/source/codepages/CPISO8859-15.TXT @@ -1,9 +1,9 @@ # # Name: ISO 8859-15 to Unicode # Unicode version: 1.1 -# Table version: 0.1 +# Table version: 0.2 # Table format: Format A -# Date: 08 January 2001 +# Date: 01 may 2001 # Authors: Toomas Soome <tsoome@ut.ee> # # Copyright (c) 1991-1995 Unicode, Inc. All Rights reserved. @@ -25,14 +25,14 @@ # General notes: # # This table contains the data the Unicode Consortium has on how -# ISO 8859-13 characters map into Unicode. +# ISO 8859-15 characters map into Unicode. # # Format: Three tab-separated columns -# Column #1 is the ISO 8859-13 code (in hex as 0xXX) +# Column #1 is the ISO 8859-15 code (in hex as 0xXX) # Column #2 is the Unicode (in hex as 0xXXXX) # Column #3 the Unicode name (follows a comment sign, '#') # -# The entries are in ISO 8859-13 order +# The entries are in ISO 8859-15 order # # Any comments or problems, contact <tsoome@ut.ee> # @@ -132,98 +132,98 @@ 0x7D 0x007D # RIGHT CURLY BRACKET 0x7E 0x007E # TILDE 0xA0 0x00A0 # NO-BREAK SPACE -0xA1 0x201D # RIGHT DOUBLE QUOTATION MARK +0xA1 0x00A1 # INVERTED EXCLAMATION MARK 0xA2 0x00A2 # CENT SIGN 0xA3 0x00A3 # POUND SIGN -0xA4 0x00A4 # CURRENCY SIGN -0xA5 0x201E # DOUBLE LOW-9 QUOTATION MARK -0xA6 0x00A6 # BROKEN BAR +0xA4 0x20AC # EURO SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x0160 # LATIN CAPITAL LETTER S WITH CARON 0xA7 0x00A7 # SECTION SIGN -0xA8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xA8 0x0161 # LATIN SMALL LETTER S WITH CARON 0xA9 0x00A9 # COPYRIGHT SIGN -0xAA 0x0156 # LATIN CAPITAL LETTER R WITH CEDILLA +0xAA 0x00AA # FEMININE ORDINAL INDICATOR 0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0xAC 0x00AC # NOT SIGN 0xAD 0x00AD # SOFT HYPHEN 0xAE 0x00AE # REGISTERED SIGN -0xAF 0x00C6 # LATIN CAPITAL LETTER AE +0xAF 0x00AF # MACRON 0xB0 0x00B0 # DEGREE SIGN 0xB1 0x00B1 # PLUS-MINUS SIGN 0xB2 0x00B2 # SUPERSCRIPT TWO 0xB3 0x00B3 # SUPERSCRIPT THREE -0xB4 0x201C # LEFT DOUBLE QUOTATION MARK +0xB4 0x017D # LATIN CAPITAL LETTER Z WITH CARON 0xB5 0x00B5 # MICRO SIGN 0xB6 0x00B6 # PILCROW SIGN 0xB7 0x00B7 # MIDDLE DOT -0xB8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xB8 0x017E # LATIN SMALL LETTER Z WITH CARON 0xB9 0x00B9 # SUPERSCRIPT ONE -0xBA 0x0157 # LATIN SMALL LETTER R WITH CEDILLA +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR 0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -0xBC 0x00BC # VULGAR FRACTION ONE QUARTER -0xBD 0x00BD # VULGAR FRACTION ONE HALF -0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS -0xBF 0x00E6 # LATIN SMALL LETTER AE -0xC0 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK -0xC1 0x012E # LATIN CAPITAL LETTER I WITH OGONEK -0xC2 0x0100 # LATIN CAPITAL LETTER A WITH MACRON -0xC3 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xBC 0x0152 # LATIN CAPITAL LIGATURE OE +0xBD 0x0153 # LATIN SMALL LIGATURE OE +0xBE 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE 0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS 0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE -0xC6 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK -0xC7 0x0112 # LATIN CAPITAL LETTER E WITH MACRON -0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE 0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE -0xCA 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE -0xCB 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE -0xCC 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA -0xCD 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA -0xCE 0x012A # LATIN CAPITAL LETTER I WITH MACRON -0xCF 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA -0xD0 0x0160 # LATIN CAPITAL LETTER S WITH CARON -0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE -0xD2 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic) +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE 0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE -0xD4 0x014C # LATIN CAPITAL LETTER O WITH MACRON +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX 0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE 0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS 0xD7 0x00D7 # MULTIPLICATION SIGN -0xD8 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK -0xD9 0x0141 # LATIN CAPITAL LETTER L WITH STROKE -0xDA 0x015A # LATIN CAPITAL LETTER S WITH ACUTE -0xDB 0x016A # LATIN CAPITAL LETTER U WITH MACRON +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX 0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS -0xDD 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE -0xDE 0x017D # LATIN CAPITAL LETTER Z WITH CARON -0xDF 0x00DF # LATIN SMALL LETTER SHARP S -0xE0 0x0105 # LATIN SMALL LETTER A WITH OGONEK -0xE1 0x012F # LATIN SMALL LETTER I WITH OGONEK -0xE2 0x0101 # LATIN SMALL LETTER A WITH MACRON -0xE3 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic) +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE 0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS 0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE -0xE6 0x0119 # LATIN SMALL LETTER E WITH OGONEK -0xE7 0x0113 # LATIN SMALL LETTER E WITH MACRON -0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE 0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE -0xEA 0x017A # LATIN SMALL LETTER Z WITH ACUTE -0xEB 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE -0xEC 0x0123 # LATIN SMALL LETTER G WITH CEDILLA -0xED 0x0137 # LATIN SMALL LETTER K WITH CEDILLA -0xEE 0x012B # LATIN SMALL LETTER I WITH MACRON -0xEF 0x013C # LATIN SMALL LETTER L WITH CEDILLA -0xF0 0x0161 # LATIN SMALL LETTER S WITH CARON -0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE -0xF2 0x0146 # LATIN SMALL LETTER N WITH CEDILLA +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic) +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE 0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE -0xF4 0x014D # LATIN SMALL LETTER O WITH MACRON +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX 0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE 0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS 0xF7 0x00F7 # DIVISION SIGN -0xF8 0x0173 # LATIN SMALL LETTER U WITH OGONEK -0xF9 0x0142 # LATIN SMALL LETTER L WITH STROKE -0xFA 0x015B # LATIN SMALL LETTER S WITH ACUTE -0xFB 0x016B # LATIN SMALL LETTER U WITH MACRON +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX 0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS -0xFD 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE -0xFE 0x017E # LATIN SMALL LETTER Z WITH CARON -0xFF 0x2019 # RIGHT SINGLE QUOTATION MARK +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic) +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/source/config.guess b/source/config.guess index adea47180fc..c339a949429 100755 --- a/source/config.guess +++ b/source/config.guess @@ -1,7 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. -# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-06-29' + # This file 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 @@ -22,72 +25,277 @@ # the same distribution terms that you use for the rest of that program. # Written by Per Bothner <bothner@cygnus.com>. -# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to <config-patches@gnu.org>. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you -# don't specify an explicit system type (host/target name). -# -# Only a few systems have been added to this list; please add others -# (but try to keep the structure clean). -# +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 8/24/94.) +# (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 - # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - news*:NEWS-OS:6.*:*) - echo mips-sony-newsos6 - exit 0 ;; + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-unknown ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE}" in + i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` + cat <<EOF >$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-cbm-sysv4 + echo m68k-unknown-sysv4 exit 0;; - amiga:NetBSD:*:*) - echo m68k-cbm-netbsd${UNAME_RELEASE} - exit 0 ;; amiga:OpenBSD:*:*) - echo m68k-cbm-openbsd${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; - Pyramid*:OSx*:*:*) + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; - sun4*:SunOS:5.*:*) + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) - echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize @@ -107,26 +315,67 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; - atari*:NetBSD:*:*) - echo m68k-atari-netbsd${UNAME_RELEASE} + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac exit 0 ;; - atari*:OpenBSD:*:*) - echo m68k-atari-openbsd${UNAME_RELEASE} + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; - sun3*:NetBSD:*:*) - echo m68k-sun-netbsd${UNAME_RELEASE} + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; sun3*:OpenBSD:*:*) - echo m68k-sun-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:NetBSD:*:*) - echo m68k-apple-netbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) - echo m68k-apple-openbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - Power*:Darwin:*:*) - echo powerpc-apple-darwin${UNAME_RELEASE} + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} @@ -134,12 +383,41 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; - mips:*:4*:UMIPS) - echo mips-mips-riscos4sysv + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; - mips:*:5*:RISCos) + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; @@ -155,15 +433,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ - -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then echo m88k-dg-dgux${UNAME_RELEASE} - else + else echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} fi - else echo i586-dg-dgux${UNAME_RELEASE} - fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 @@ -181,15 +462,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i[34]86:AIX:*:*) + i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include <sys/systemcfg.h> main() @@ -200,8 +489,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit(0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 @@ -209,8 +499,9 @@ EOF echo rs6000-ibm-aix3.2 fi exit 0 ;; - *:AIX:*:4) - if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -218,7 +509,7 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=4.${UNAME_RELEASE} + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; @@ -228,8 +519,8 @@ EOF ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -243,18 +534,76 @@ EOF hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; - 9000/[3478]??:HP-UX:*:*) + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;; - 9000/8?? ) HP_ARCH=hppa1.0 ;; + 9000/[678][0-9][0-9]) + case "${HPUX_REV}" in + 11.[0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + esac ;; + esac + fi ;; + esac + if [ "${HP_ARCH}" = "" ]; then + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + eval $set_cc_for_build + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; esac - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; 3050*:HI-UX:*:*) - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include <unistd.h> int main () @@ -279,8 +628,9 @@ EOF exit (0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) @@ -289,15 +639,28 @@ EOF 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; @@ -316,126 +679,256 @@ EOF C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; - CRAY*T3E:*:*:*) - echo t3e-cray-unicos_mk - exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; - CRAY*C90:*:*:*) - echo c90-cray-unicos${UNAME_RELEASE} + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; - hp3[0-9][05]:NetBSD:*:*) - echo m68k-hp-netbsd${UNAME_RELEASE} + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - hp3[0-9][05]:OpenBSD:*:*) - echo m68k-hp-openbsd${UNAME_RELEASE} + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; - i[34]86:BSD/386:*:* | *:BSD/OS:*:*) + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; - *:NetBSD:*:*) - echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; - *:QNX:*:4*) - echo i386-qnx-qnx4 - exit 0 ;; i*:CYGWIN*:*) - echo i386-unknown-cygwin32 + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin32 + echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; - *:Linux:*:*) + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in + big) echo mips-unknown-linux-gnu && exit 0 ;; + little) echo mipsel-unknown-linux-gnu && exit 0 ;; + esac + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev67 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so - # first see if it will tell us. - ld_help_string=`ld --help 2>&1` - if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then - echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then - echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then - echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then - echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then - echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0 - elif test "${UNAME_MACHINE}" = "alpha" ; then - echo alpha-unknown-linux ; exit 0 - else - # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us - # useful --help. Gcc wants to distinguish between linuxoldld and linuxaout. - test ! -d /usr/lib/ldscripts/. \ - && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0 - # Determine whether the default compiler is a.out or elf - cat >dummy.c <<EOF -main(argc, argv) -int argc; -char *argv[]; -{ + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_supported_targets=`cd /; ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c <<EOF +#include <features.h> +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #ifdef __ELF__ - printf ("%s-unknown-linux\n", argv[1]); +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-pc-linux-gnu\n", argv[1]); +# else + printf ("%s-pc-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-pc-linux-gnulibc1\n", argv[1]); +# endif #else - printf ("%s-unknown-linuxaout\n", argv[1]); + printf ("%s-pc-linux-gnuaout\n", argv[1]); #endif return 0; } EOF - ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy - fi ;; -# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions -# are messed up and put the nodename in both sysname and nodename. - i[34]86:DYNIX/ptx:4*:*) + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; - i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*) + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; - i[34]86:*:3.2:*) + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL elif /bin/uname -X 2>/dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 - echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else - echo ${UNAME_MACHINE}-unknown-sysv32 + echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; - *:UnixWare:*:* | *:OpenUNIX:*:*) - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; Intel:Mach:3*:*) - echo i386-unknown-mach3 + echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 @@ -451,30 +944,42 @@ EOF # "miniframe" echo m68010-convergent-sysv exit 0 ;; - M680[234]0:*:R3V[567]*:*) + M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0) - uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3 && exit 0 - uname -p 2>/dev/null | grep entium >/dev/null \ - && echo i586-ncr-sysv4.3 && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - uname -p 2>/dev/null | grep 86 >/dev/null \ + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; - m680[234]0:LynxOS:2.[23]*:*) - echo m68k-lynx-lynxos${UNAME_RELEASE} + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; - i[34]86:LynxOS:2.[23]*:*) - echo i386-lynx-lynxos${UNAME_RELEASE} + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; - TSUNAMI:LynxOS:2.[23]*:*) - echo sparc-lynx-lynxos${UNAME_RELEASE} + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; - rs6000:LynxOS:2.[23]*:*) - echo rs6000-lynx-lynxos${UNAME_RELEASE} + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 @@ -487,25 +992,117 @@ EOF echo ns32k-sni-sysv fi exit 0 ;; - *:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; - R3000:*System_V*:*:*) + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[KW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -cat >dummy.c <<EOF +cat >$dummy.c <<EOF #ifdef _SEQUENT_ # include <sys/types.h> # include <sys/utsname.h> @@ -543,7 +1140,10 @@ main () #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3"); + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif @@ -560,7 +1160,7 @@ main () #endif #if defined (__386BSD__) - printf ("i386-unknown-bsd\n"); exit (0); + printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) @@ -588,11 +1188,24 @@ main () #endif #if defined (vax) -#if !defined (ultrix) - printf ("vax-dec-bsd\n"); exit (0); -#else - printf ("vax-dec-ultrix\n"); exit (0); -#endif +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif #endif #if defined (alliant) && defined (i860) @@ -603,8 +1216,9 @@ main () } EOF -${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 -rm -f dummy.c dummy +eval $set_cc_for_build +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy # Apollos put the system type in the environment. @@ -636,6 +1250,48 @@ then esac fi -#echo '(Unable to guess system type)' 1>&2 +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + ftp://ftp.gnu.org/pub/gnu/config/ + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/source/config.sub b/source/config.sub index 8f8f708aca9..578b302738e 100755 --- a/source/config.sub +++ b/source/config.sub @@ -1,9 +1,13 @@ #! /bin/sh -# Configuration validation subroutine script, version 1.1. -# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-06-08' + # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. +# can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -25,6 +29,8 @@ # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. +# Please send patches to <config-patches@gnu.org>. +# # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. @@ -41,32 +47,87 @@ # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -if [ x$1 = x ] -then - echo Configuration name missing. 1>&2 - echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 - echo "or $0 ALIAS" 1>&2 - echo where ALIAS is a recognized configuration type. 1>&2 - exit 1 -fi +me=`echo "$0" | sed -e 's,.*/,,'` -# First pass through any local machine types. -case $1 in - *local*) - echo $1 - exit 0 - ;; - *) - ;; +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS (if any). -basic_machine=`echo $1 | sed 's/-[^-]*$//'` -if [ $basic_machine != $1 ] -then os=`echo $1 | sed 's/.*-/-/'` -else os=; fi +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also @@ -81,52 +142,64 @@ case $os in -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp ) + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) os= basic_machine=$1 ;; - -sim | -cisco | -oki | -wec | -winbond ) # CYGNUS LOCAL + -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; - -apple*) # CYGNUS LOCAL - os= - basic_machine=$1 + -scout) ;; - -scout) # CYGNUS LOCAL + -wrs) + os=-vxworks + basic_machine=$1 ;; - -wrs) # CYGNUS LOCAL - os=vxworks + -chorusos*) + os=-chorusos basic_machine=$1 ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; -hiux*) os=-hiuxwe2 ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco4) os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos @@ -137,50 +210,90 @@ case $os in -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. - tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | armeb \ - | armel | pyramid \ - | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ - | alpha | we32k | ns16k | clipper | sparclite | i370 | s390 | sh \ - | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \ - | pdp11 | mips64el | mips64orion | mips64orionel \ - | sparc | sparc8 | supersparc | microsparc | ultrasparc) + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \ + | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \ + | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | sh[34] \ + | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp10 | pdp11 \ + | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \ + | v850 | c4x \ + | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \ + | pj | pjl | h8500 | z8k) basic_machine=$basic_machine-unknown ;; - m88110 | m680[012346]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. basic_machine=$basic_machine-unknown + os=-none ;; - mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith - basic_machine=$basic_machine-unknown + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. - vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ - | sparc-* | ns32k-* | fx80-* | arm-* | arme[lb]-* | c[123]* \ - | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ - | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ - | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ - | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ - | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* \ - | mips64-* | mipsel-* | mips64el-* | mips64orion-* \ - | mips64orionel-* | sparc8-* | supersparc-* | microsparc-* | ultrasparc-*) - ;; - m88110-* | m680[012346]0-* | m683?2-* | m68360-* | z8k-* | h8500-*) # CYGNUS LOCAL - ;; - mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \ + | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \ + | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \ + | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \ + | [cjt]90-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \ + | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) # CYGNUS LOCAL + 386bsd) basic_machine=i386-unknown os=-bsd ;; @@ -190,11 +303,11 @@ case $basic_machine in 3b*) basic_machine=we32k-att ;; - a29khif) # CYGNUS LOCAL + a29khif) basic_machine=a29k-amd os=-udi ;; - adobe68k) # CYGNUS LOCAL + adobe68k) basic_machine=m68010-adobe os=-scout ;; @@ -213,40 +326,32 @@ case $basic_machine in os=-sysv ;; amiga | amiga-*) - basic_machine=m68k-cbm + basic_machine=m68k-unknown ;; - amigados) - basic_machine=m68k-cbm - os=-amigados + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos ;; amigaunix | amix) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; - apollo68bsd) # CYGNUS LOCAL + apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; - arm | armel | armeb) - basic_machine=arm-arm - os=-aout + aux) + basic_machine=m68k-apple + os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; - [ctj]90-cray) - basic_machine=c90-cray - os=-unicos - ;; - t3e-cray) - basic_machine=t3e-cray - os=-unicos_mk - ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -275,9 +380,16 @@ case $basic_machine in basic_machine=cray2-cray os=-unicos ;; + [cjt]90) + basic_machine=${basic_machine}-cray + os=-unicos + ;; crds | unos) basic_machine=m68k-crds ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; da30 | da30-*) basic_machine=m68k-da30 ;; @@ -311,7 +423,7 @@ case $basic_machine in encore | umax | mmax) basic_machine=ns32k-encore ;; - es1800 | OSE68k | ose68k | ose | OSE) # CYGNUS LOCAL + es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; @@ -325,6 +437,10 @@ case $basic_machine in basic_machine=tron-gmicro os=-sysv ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -333,11 +449,11 @@ case $basic_machine in basic_machine=h8300-hitachi os=-hms ;; - h8300xray) # CYGNUS LOCAL + h8300xray) basic_machine=h8300-hitachi os=-xray ;; - h8500hms) # CYGNUS LOCAL + h8500hms) basic_machine=h8500-hitachi os=-hms ;; @@ -356,71 +472,74 @@ case $basic_machine in basic_machine=m68k-hp os=-hpux ;; - w89k-*) # CYGNUS LOCAL - basic_machine=hppa1.1-winbond - os=-proelf - ;; - op50n-*) # CYGNUS LOCAL - basic_machine=hppa1.1-oki - os=-proelf - ;; - op60c-*) # CYGNUS LOCAL - basic_machine=hppa1.1-oki - os=-proelf - ;; - hppro) # CYGNUS LOCAL - basic_machine=hppa1.1-hp - os=-proelf - ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; - hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppaosf) # CYGNUS LOCAL + hppa-next) + os=-nextstep3 + ;; + hppaosf) basic_machine=hppa1.1-hp os=-osf ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; i370-ibm* | ibm*) basic_machine=i370-ibm - os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? - i[3456]86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; - i[3456]86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; - i[3456]86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; - i[3456]86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; - i386mach) # CYGNUS LOCAL + i386mach) basic_machine=i386-mach os=-mach ;; - i386-vsta | vsta) # CYGNUS LOCAL + i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; - i386-go32 | go32) # CYGNUS LOCAL - basic_machine=i386-unknown - os=-go32 - ;; iris | iris4d) basic_machine=mips-sgi case $os in @@ -446,31 +565,59 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; miniframe) basic_machine=m68000-convergent ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; - monitor) # CYGNUS LOCAL + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) basic_machine=m68k-rom68k os=-coff ;; - msdos) # CYGNUS LOCAL - basic_machine=i386-unknown + msdos) + basic_machine=i386-pc os=-msdos ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) - basic_machine=i386-unknown # CYGNUS LOCAL + basic_machine=i386-unknown os=-netbsd ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos @@ -483,7 +630,7 @@ case $basic_machine in basic_machine=mips-sony os=-newsos ;; - necv70) # CYGNUS LOCAL + necv70) basic_machine=v70-nec os=-sysv ;; @@ -512,14 +659,29 @@ case $basic_machine in basic_machine=i960-intel os=-nindy ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; np1) basic_machine=np1-gould ;; - OSE68000 | ose68000) # CYGNUS LOCAL + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; - os68k) # CYGNUS LOCAL + os68k) basic_machine=m68k-none os=-os68k ;; @@ -540,30 +702,28 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; - pentium | p5) - basic_machine=i586-intel + pentium | p5 | k5 | k6 | nexgen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc ;; - pentiumpro | p6) - basic_machine=i686-intel + pentiumii | pentium2) + basic_machine=i686-pc ;; - pentium-* | p5-*) + pentium-* | p5-* | k5-* | k6-* | nexgen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumpro-* | p6-*) + pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - k5) - # We don't have specific support for AMD's K5 yet, so just call it a Pentium - basic_machine=i586-amd - ;; - nexgen) - # We don't have specific support for Nexgen yet, so just call it a Pentium - basic_machine=i586-nexgen + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; - power) basic_machine=rs6000-ibm + power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; @@ -578,7 +738,11 @@ case $basic_machine in ps2) basic_machine=i386-ibm ;; - rom68k) # CYGNUS LOCAL + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) basic_machine=m68k-rom68k os=-coff ;; @@ -588,11 +752,7 @@ case $basic_machine in rtpc | rtpc-*) basic_machine=romp-ibm ;; - s390*) - basic_machine=s390-ibm - os=-linux - ;; - sa29200) # CYGNUS LOCAL + sa29200) basic_machine=a29k-amd os=-udi ;; @@ -603,24 +763,10 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; - sparclite-wrs) # CYGNUS LOCAL + sparclite-wrs) basic_machine=sparclite-wrs os=-vxworks ;; - sparcfrw) # CYGNUS LOCAL - basic_machine=sparcfrw-sun - os=-sunos4 - ;; - sparcfrwcompat) # CYGNUS LOCAL - basic_machine=sparcfrwcompat-sun - os=-sunos4 - ;; - sparclitefrw) # CYGNUS LOCAL - basic_machine=sparclitefrw-fujitsu - ;; - sparclitefrwcompat) # CYGNUS LOCAL - basic_machine=sparclitefrwcompat-fujitsu - ;; sps7) basic_machine=m68k-bull os=-sysv2 @@ -628,10 +774,10 @@ case $basic_machine in spur) basic_machine=spur-unknown ;; - st2000) # CYGNUS LOCAL + st2000) basic_machine=m68k-tandem ;; - stratus) # CYGNUS LOCAL + stratus) basic_machine=i860-stratus os=-sysv4 ;; @@ -675,10 +821,28 @@ case $basic_machine in sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; symmetry) basic_machine=i386-sequent os=-dynix ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; tower | tower-32) basic_machine=m68k-ncr ;; @@ -690,7 +854,7 @@ case $basic_machine in basic_machine=a29k-nyu os=-sym1 ;; - v810 | necv810) # CYGNUS LOCAL + v810 | necv810) basic_machine=v810-nec os=-none ;; @@ -702,6 +866,9 @@ case $basic_machine in basic_machine=vax-dec os=-vms ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; vxworks960) basic_machine=i960-wrs os=-vxworks @@ -710,13 +877,21 @@ case $basic_machine in basic_machine=m68k-wrs os=-vxworks ;; - vxworks29k) # CYGNUS LOCAL - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) # CYGNUS LOCAL - basic_machine=w65-wdc - os=-none + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt ;; xmp) basic_machine=xmp-cray @@ -725,7 +900,7 @@ case $basic_machine in xps | xps100) basic_machine=xps100-honeywell ;; - z8k-*-coff) # CYGNUS LOCAL + z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; @@ -736,17 +911,21 @@ case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. - w89k) # CYGNUS LOCAL + w89k) basic_machine=hppa1.1-winbond ;; - op50n) # CYGNUS LOCAL + op50n) basic_machine=hppa1.1-oki ;; - op60c) # CYGNUS LOCAL + op60c) basic_machine=hppa1.1-oki ;; mips) - basic_machine=mips-mips + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi ;; romp) basic_machine=romp-ibm @@ -757,13 +936,20 @@ case $basic_machine in vax) basic_machine=vax-dec ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; - sparc) + sh3 | sh4) + basic_machine=sh-unknown + ;; + sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) @@ -775,12 +961,19 @@ case $basic_machine in orion105) basic_machine=clipper-highlevel ;; - mac | mpw | mac-mpw) # CYGNUS LOCAL + mac | mpw | mac-mpw) basic_machine=m68k-apple ;; - pmac | pmac-mpw) # CYGNUS LOCAL + pmac | pmac-mpw) basic_machine=powerpc-apple ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 @@ -804,6 +997,8 @@ esac if [ x"$os" != x"" ] then case $os in + # First match some system type aliases + # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` @@ -811,42 +1006,72 @@ case $os in -solaris) os=-solaris2 ;; - -unixware* | svr4*) + -svr4*) os=-sysv4 ;; + -unixware*) + os=-sysv4.2uw + ;; -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux|'` + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. - # Each alternative must end in a *, to match a version number. + # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -lites* | -minix* | -genix* | -ultrix* | -irix* \ - | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \ + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigados* | -msdos* | -moss* | -newsos* | -unicos* | -aos* \ - | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ - | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -freebsd* | -openbsd* \ - | -riscix* | -lites* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi \ - | -eabi* | -ieee* | -qnx*) - ;; - # CYGNUS LOCAL - -go32 | -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -proelf | -os9* \ - | -macos* | -mpw* | -magic* | -pe* | -win32) - ;; - -mac*) # CYGNUS LOCAL + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; -osfrose*) os=-osfrose ;; @@ -862,12 +1087,18 @@ case $os in -acis*) os=-aos ;; - -386bsd) # CYGNUS LOCAL + -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` @@ -893,15 +1124,18 @@ case $os in # This must come after -sysvr4. -sysv*) ;; - -ose*) # CYGNUS LOCAL + -ose*) os=-ose ;; - -es1800*) # CYGNUS LOCAL + -es1800*) os=-ose ;; -xenix) os=-xenix ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; -none) ;; *) @@ -927,6 +1161,15 @@ case $basic_machine in *-acorn) os=-riscix1.2 ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp10-*) + os=-tops20 + ;; pdp11-*) os=-none ;; @@ -945,10 +1188,13 @@ case $basic_machine in # default. # os=-sunos4 ;; - m68*-cisco) # CYGNUS LOCAL + m68*-cisco) os=-aout ;; - mips*-cisco) # CYGNUS LOCAL + mips*-cisco) + os=-elf + ;; + mips*-*) os=-elf ;; *-tti) # must be before sparc entry or we get the wrong os. @@ -957,16 +1203,19 @@ case $basic_machine in sparc-* | *-sun) os=-sunos4.1.1 ;; + *-be) + os=-beos + ;; *-ibm) os=-aix ;; - *-wec) # CYGNUS LOCAL + *-wec) os=-proelf ;; - *-winbond) # CYGNUS LOCAL + *-winbond) os=-proelf ;; - *-oki) # CYGNUS LOCAL + *-oki) os=-proelf ;; *-hp) @@ -979,7 +1228,7 @@ case $basic_machine in os=-sysv ;; *-cbm) - os=-amigados + os=-amigaos ;; *-dg) os=-dgux @@ -993,6 +1242,9 @@ case $basic_machine in m88k-omron*) os=-luna ;; + *-next ) + os=-nextstep + ;; *-sequent) os=-ptx ;; @@ -1026,15 +1278,21 @@ case $basic_machine in *-masscomp) os=-rtu ;; - *-rom68k) # CYGNUS LOCAL + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) os=-coff ;; - *-*bug) # CYGNUS LOCAL + *-*bug) os=-coff ;; - *-apple) # CYGNUS LOCAL + *-apple) os=-macos ;; + *-atari*) + os=-mint + ;; *) os=-none ;; @@ -1053,18 +1311,18 @@ case $basic_machine in -sunos*) vendor=sun ;; - -bosx*) # CYGNUS LOCAL - vendor=bull - ;; - -lynxos*) - vendor=lynx - ;; -aix*) vendor=ibm ;; + -beos*) + vendor=be + ;; -hpux*) vendor=hp ;; + -mpeix*) + vendor=hp + ;; -hiux*) vendor=hitachi ;; @@ -1080,24 +1338,38 @@ case $basic_machine in -genix*) vendor=ns ;; - -mvs*) + -mvs* | -opened*) vendor=ibm ;; -ptx*) vendor=sequent ;; - -vxworks*) + -vxsim* | -vxworks*) vendor=wrs ;; - -hms*) # CYGNUS LOCAL + -aux*) + vendor=apple + ;; + -hms*) vendor=hitachi ;; - -mpw* | -macos*) # CYGNUS LOCAL + -mpw* | -macos*) vendor=apple ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/source/configure b/source/configure index 1de9bd83157..1a8274f86aa 100755 --- a/source/configure +++ b/source/configure @@ -15,15 +15,15 @@ ac_default_prefix=/usr/local/samba ac_help="$ac_help --with-fhs use FHS-compliant paths [default=no]" ac_help="$ac_help - --with-privatedir=DIR Where to put smbpasswd ($privatedir)" + --with-privatedir=DIR Where to put smbpasswd ($ac_default_prefix/private)" ac_help="$ac_help - --with-lockdir=DIR Where to put lock files ($lockdir)" + --with-lockdir=DIR Where to put lock files ($ac_default_prefix/var/locks)" ac_help="$ac_help - --with-swatdir=DIR Where to put SWAT files ($swatdir)" + --with-swatdir=DIR Where to put SWAT files ($ac_default_prefix/swat)" ac_help="$ac_help - --with-configdir=DIR Where to put configuration files ($configdir)" + --with-configdir=DIR Where to put configuration files (\$libdir)" ac_help="$ac_help - --with-codepagedir=DIR Where to put codepage files ($codepagedir)" + --with-codepagedir=DIR Where to put codepage files (\$libdir/codepages)" ac_help="$ac_help --enable-debug turn on debugging [default=no]" ac_help="$ac_help @@ -64,6 +64,9 @@ ac_help="$ac_help --with-pam Include PAM password database support --without-pam Don't include PAM password database support (default)" ac_help="$ac_help + --with-pam_smbpass Include the smbpass PAM module + --without-pam_smbpass Don't include the smbpass PAM module (default)" +ac_help="$ac_help --with-nisplus Include NISPLUS password database support --without-nisplus Don't include NISPLUS password database support (default)" ac_help="$ac_help @@ -751,6 +754,7 @@ fi + # compile with optimization and without debugging by default CFLAGS="-O ${CFLAGS}" @@ -768,7 +772,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:772: checking for $ac_word" >&5 +echo "configure:776: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -798,7 +802,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:802: checking for $ac_word" >&5 +echo "configure:806: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -849,7 +853,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:853: checking for $ac_word" >&5 +echo "configure:857: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -881,7 +885,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:885: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:889: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -892,12 +896,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 896 "configure" +#line 900 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -923,12 +927,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:927: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:931: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:932: checking whether we are using GNU C" >&5 +echo "configure:936: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -937,7 +941,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:941: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:945: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -956,7 +960,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:960: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:964: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1018,7 +1022,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1022: checking for a BSD compatible install" >&5 +echo "configure:1026: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1075,7 +1079,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1079: checking for $ac_word" >&5 +echo "configure:1083: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1180,7 +1184,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:1184: checking host system type" >&5 +echo "configure:1188: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -1201,7 +1205,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:1205: checking build system type" >&5 +echo "configure:1209: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -1221,7 +1225,7 @@ echo "$ac_t""$build" 1>&6 # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1225: checking for $ac_word" >&5 +echo "configure:1229: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1260,7 +1264,7 @@ ac_prog=ld if test "$ac_cv_prog_gcc" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 -echo "configure:1264: checking for ld used by GCC" >&5 +echo "configure:1268: checking for ld used by GCC" >&5 ac_prog=`($CC -print-prog-name=ld) 2>&5` case "$ac_prog" in # Accept absolute paths. @@ -1284,10 +1288,10 @@ echo "configure:1264: checking for ld used by GCC" >&5 esac elif test "$with_gnu_ld" = yes; then echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:1288: checking for GNU ld" >&5 +echo "configure:1292: checking for GNU ld" >&5 else echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:1291: checking for non-GNU ld" >&5 +echo "configure:1295: checking for non-GNU ld" >&5 fi if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1322,7 +1326,7 @@ else fi test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:1326: checking if the linker ($LD) is GNU ld" >&5 +echo "configure:1330: checking if the linker ($LD) is GNU ld" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1338,7 +1342,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 -echo "configure:1342: checking for BSD-compatible nm" >&5 +echo "configure:1346: checking for BSD-compatible nm" >&5 if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1374,7 +1378,7 @@ NM="$ac_cv_path_NM" echo "$ac_t""$NM" 1>&6 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1378: checking whether ln -s works" >&5 +echo "configure:1382: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1423,8 +1427,8 @@ test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" case "$lt_target" in *-*-irix6*) # Find out which ABI we are using. - echo '#line 1427 "configure"' > conftest.$ac_ext - if { (eval echo configure:1428: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + echo '#line 1431 "configure"' > conftest.$ac_ext + if { (eval echo configure:1432: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then case "`/usr/bin/file conftest.o`" in *32-bit*) LD="${LD-ld} -32" @@ -1445,19 +1449,19 @@ case "$lt_target" in SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 -echo "configure:1449: checking whether the C compiler needs -belf" >&5 +echo "configure:1453: checking whether the C compiler needs -belf" >&5 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1454 "configure" +#line 1458 "configure" #include "confdefs.h" int main() { ; return 0; } EOF -if { (eval echo configure:1461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1465: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* lt_cv_cc_needs_belf=yes else @@ -1562,10 +1566,10 @@ exec 5>>./config.log if test "x$CC" != xcc; then echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6 -echo "configure:1566: checking whether $CC and cc understand -c and -o together" >&5 +echo "configure:1570: checking whether $CC and cc understand -c and -o together" >&5 else echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6 -echo "configure:1569: checking whether cc understands -c and -o together" >&5 +echo "configure:1573: checking whether cc understands -c and -o together" >&5 fi set dummy $CC; ac_cc="`echo $2 | sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`" @@ -1577,16 +1581,16 @@ else # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5' -if { (eval echo configure:1581: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && - test -f conftest.o && { (eval echo configure:1582: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; +if { (eval echo configure:1585: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && + test -f conftest.o && { (eval echo configure:1586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. - if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1587: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then + if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1591: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then ac_try='cc -c conftest.c -o conftest.o 1>&5' - if { (eval echo configure:1589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && - test -f conftest.o && { (eval echo configure:1590: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; + if { (eval echo configure:1593: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && + test -f conftest.o && { (eval echo configure:1594: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; then # cc works too. : @@ -1620,20 +1624,20 @@ fi echo $ac_n "checking that the C compiler understands volatile""... $ac_c" 1>&6 -echo "configure:1624: checking that the C compiler understands volatile" >&5 +echo "configure:1628: checking that the C compiler understands volatile" >&5 if eval "test \"`echo '$''{'samba_cv_volatile'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1630 "configure" +#line 1634 "configure" #include "confdefs.h" #include <sys/types.h> int main() { volatile int i = 0 ; return 0; } EOF -if { (eval echo configure:1637: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1641: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_volatile=yes else @@ -1683,7 +1687,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:1687: checking host system type" >&5 +echo "configure:1691: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -1704,7 +1708,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:1708: checking target system type" >&5 +echo "configure:1712: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -1722,7 +1726,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:1726: checking build system type" >&5 +echo "configure:1730: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -1756,7 +1760,7 @@ esac echo $ac_n "checking config.cache system type""... $ac_c" 1>&6 -echo "configure:1760: checking config.cache system type" >&5 +echo "configure:1764: checking config.cache system type" >&5 if { test x"${ac_cv_host_system_type+set}" = x"set" && test x"$ac_cv_host_system_type" != x"$host"; } || { test x"${ac_cv_build_system_type+set}" = x"set" && @@ -1781,7 +1785,7 @@ case "$host_os" in # Try to work out if this is the native HPUX compiler that uses the -Ae flag. *hpux*) echo $ac_n "checking whether ${CC-cc} accepts -Ae""... $ac_c" 1>&6 -echo "configure:1785: checking whether ${CC-cc} accepts -Ae" >&5 +echo "configure:1789: checking whether ${CC-cc} accepts -Ae" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_Ae'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1865,14 +1869,14 @@ EOF *sysv4*) if test $host = mips-sni-sysv4 ; then echo $ac_n "checking for LFS support""... $ac_c" 1>&6 -echo "configure:1869: checking for LFS support" >&5 +echo "configure:1873: checking for LFS support" >&5 old_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS" if test "$cross_compiling" = yes; then SINIX_LFS_SUPPORT=cross else cat > conftest.$ac_ext <<EOF -#line 1876 "configure" +#line 1880 "configure" #include "confdefs.h" #include <unistd.h> @@ -1884,7 +1888,7 @@ exit(1); #endif } EOF -if { (eval echo configure:1888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then SINIX_LFS_SUPPORT=yes else @@ -1911,14 +1915,14 @@ fi # *linux*) echo $ac_n "checking for LFS support""... $ac_c" 1>&6 -echo "configure:1915: checking for LFS support" >&5 +echo "configure:1919: checking for LFS support" >&5 old_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS" + CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" if test "$cross_compiling" = yes; then LINUX_LFS_SUPPORT=cross else cat > conftest.$ac_ext <<EOF -#line 1922 "configure" +#line 1926 "configure" #include "confdefs.h" #include <unistd.h> @@ -1956,7 +1960,7 @@ main() { } EOF -if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LINUX_LFS_SUPPORT=yes else @@ -1970,21 +1974,21 @@ fi CPPFLAGS="$old_CPPFLAGS" if test x$LINUX_LFS_SUPPORT = xyes ; then - CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS" + CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" fi echo "$ac_t""$LINUX_LFS_SUPPORT" 1>&6 ;; *hurd*) echo $ac_n "checking for LFS support""... $ac_c" 1>&6 -echo "configure:1981: checking for LFS support" >&5 +echo "configure:1985: checking for LFS support" >&5 old_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS" if test "$cross_compiling" = yes; then GLIBC_LFS_SUPPORT=cross else cat > conftest.$ac_ext <<EOF -#line 1988 "configure" +#line 1992 "configure" #include "confdefs.h" #include <unistd.h> @@ -1996,7 +2000,7 @@ exit(1); #endif } EOF -if { (eval echo configure:2000: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then GLIBC_LFS_SUPPORT=yes else @@ -2018,21 +2022,21 @@ fi esac echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:2022: checking for inline" >&5 +echo "configure:2026: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <<EOF -#line 2029 "configure" +#line 2033 "configure" #include "confdefs.h" int main() { } $ac_kw foo() { ; return 0; } EOF -if { (eval echo configure:2036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2040: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -2058,7 +2062,7 @@ EOF esac echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:2062: checking how to run the C preprocessor" >&5 +echo "configure:2066: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -2073,13 +2077,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF -#line 2077 "configure" +#line 2081 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2087: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2090,13 +2094,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF -#line 2094 "configure" +#line 2098 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2100: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2104: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2107,13 +2111,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext <<EOF -#line 2111 "configure" +#line 2115 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2117: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2121: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2138,12 +2142,12 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:2142: checking for ANSI C header files" >&5 +echo "configure:2146: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2147 "configure" +#line 2151 "configure" #include "confdefs.h" #include <stdlib.h> #include <stdarg.h> @@ -2151,7 +2155,7 @@ else #include <float.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2159: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2168,7 +2172,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext <<EOF -#line 2172 "configure" +#line 2176 "configure" #include "confdefs.h" #include <string.h> EOF @@ -2186,7 +2190,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext <<EOF -#line 2190 "configure" +#line 2194 "configure" #include "confdefs.h" #include <stdlib.h> EOF @@ -2207,7 +2211,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <<EOF -#line 2211 "configure" +#line 2215 "configure" #include "confdefs.h" #include <ctype.h> #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -2218,7 +2222,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:2222: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -2246,12 +2250,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:2250: checking for $ac_hdr that defines DIR" >&5 +echo "configure:2254: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2255 "configure" +#line 2259 "configure" #include "confdefs.h" #include <sys/types.h> #include <$ac_hdr> @@ -2259,7 +2263,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:2263: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2267: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -2284,7 +2288,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:2288: checking for opendir in -ldir" >&5 +echo "configure:2292: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2292,7 +2296,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <<EOF -#line 2296 "configure" +#line 2300 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -2303,7 +2307,7 @@ int main() { opendir() ; return 0; } EOF -if { (eval echo configure:2307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2325,7 +2329,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:2329: checking for opendir in -lx" >&5 +echo "configure:2333: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2333,7 +2337,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <<EOF -#line 2337 "configure" +#line 2341 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -2344,7 +2348,7 @@ int main() { opendir() ; return 0; } EOF -if { (eval echo configure:2348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2367,12 +2371,12 @@ fi fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:2371: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:2375: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2376 "configure" +#line 2380 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/time.h> @@ -2381,7 +2385,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:2385: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -2402,12 +2406,12 @@ EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 -echo "configure:2406: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo "configure:2410: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2411 "configure" +#line 2415 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/wait.h> @@ -2423,7 +2427,7 @@ wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF -if { (eval echo configure:2427: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2431: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else @@ -2447,17 +2451,17 @@ for ac_hdr in arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2451: checking for $ac_hdr" >&5 +echo "configure:2455: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2456 "configure" +#line 2460 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2461: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2465: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2487,17 +2491,17 @@ for ac_hdr in unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2491: checking for $ac_hdr" >&5 +echo "configure:2495: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2496 "configure" +#line 2500 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2501: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2505: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2527,17 +2531,17 @@ for ac_hdr in compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2531: checking for $ac_hdr" >&5 +echo "configure:2535: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2536 "configure" +#line 2540 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2541: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2545: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2563,21 +2567,21 @@ else fi done -for ac_hdr in sys/param.h ctype.h sys/un.h sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h +for ac_hdr in sys/param.h ctype.h sys/un.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/mode.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2571: checking for $ac_hdr" >&5 +echo "configure:2575: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2576 "configure" +#line 2580 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2581: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2585: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2603,21 +2607,21 @@ else fi done -for ac_hdr in sys/mman.h sys/filio.h sys/priv.h string.h strings.h stdlib.h sys/socket.h +for ac_hdr in sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2611: checking for $ac_hdr" >&5 +echo "configure:2615: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2616 "configure" +#line 2620 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2621: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2625: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2647,17 +2651,17 @@ for ac_hdr in sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h term do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2651: checking for $ac_hdr" >&5 +echo "configure:2655: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2656 "configure" +#line 2660 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2661: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2687,17 +2691,17 @@ for ac_hdr in sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2691: checking for $ac_hdr" >&5 +echo "configure:2695: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2696 "configure" +#line 2700 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2701: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2705: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2723,6 +2727,47 @@ else fi done +for ac_hdr in security/pam_modules.h security/_pam_macros.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2735: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2740 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2745: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + # # HPUX has a bug in that including shadow.h causes a re-definition of MAXINT. # This causes configure to fail to detect it. Check for shadow separately on HPUX. @@ -2730,14 +2775,14 @@ done case "$host_os" in *hpux*) cat > conftest.$ac_ext <<EOF -#line 2734 "configure" +#line 2779 "configure" #include "confdefs.h" #include <shadow.h> int main() { struct spwd testme ; return 0; } EOF -if { (eval echo configure:2741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_shadow_h=yes else @@ -2759,17 +2804,17 @@ for ac_hdr in shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2763: checking for $ac_hdr" >&5 +echo "configure:2808: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2768 "configure" +#line 2813 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2773: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2818: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2795,21 +2840,21 @@ else fi done -for ac_hdr in nss.h sys/security.h security/pam_appl.h +for ac_hdr in nss.h nss_common.h sys/security.h security/pam_appl.h security/pam_modules.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2803: checking for $ac_hdr" >&5 +echo "configure:2848: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2808 "configure" +#line 2853 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2813: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2858: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2839,17 +2884,17 @@ for ac_hdr in stropts.h poll.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2843: checking for $ac_hdr" >&5 +echo "configure:2888: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2848 "configure" +#line 2893 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2853: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2879,17 +2924,17 @@ for ac_hdr in sys/capability.h syscall.h sys/syscall.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2883: checking for $ac_hdr" >&5 +echo "configure:2928: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2888 "configure" +#line 2933 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2893: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2915,21 +2960,21 @@ else fi done -for ac_hdr in sys/acl.h sys/cdefs.h glob.h acl/acl.h +for ac_hdr in sys/acl.h sys/cdefs.h glob.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2923: checking for $ac_hdr" >&5 +echo "configure:2968: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2928 "configure" +#line 2973 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2933: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2978: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2961,17 +3006,17 @@ for ac_hdr in utmp.h utmpx.h lastlog.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2965: checking for $ac_hdr" >&5 +echo "configure:3010: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2970 "configure" +#line 3015 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3020: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3003,17 +3048,17 @@ for ac_hdr in sys/fs/vx_quota.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3007: checking for $ac_hdr" >&5 +echo "configure:3052: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3012 "configure" +#line 3057 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3017: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3062: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3041,7 +3086,7 @@ done echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:3045: checking size of int" >&5 +echo "configure:3090: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3049,7 +3094,7 @@ else ac_cv_sizeof_int=cross else cat > conftest.$ac_ext <<EOF -#line 3053 "configure" +#line 3098 "configure" #include "confdefs.h" #include <stdio.h> main() @@ -3060,7 +3105,7 @@ main() exit(0); } EOF -if { (eval echo configure:3064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3109: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -3080,7 +3125,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:3084: checking size of long" >&5 +echo "configure:3129: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3088,7 +3133,7 @@ else ac_cv_sizeof_long=cross else cat > conftest.$ac_ext <<EOF -#line 3092 "configure" +#line 3137 "configure" #include "confdefs.h" #include <stdio.h> main() @@ -3099,7 +3144,7 @@ main() exit(0); } EOF -if { (eval echo configure:3103: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3148: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -3119,7 +3164,7 @@ EOF echo $ac_n "checking size of short""... $ac_c" 1>&6 -echo "configure:3123: checking size of short" >&5 +echo "configure:3168: checking size of short" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3127,7 +3172,7 @@ else ac_cv_sizeof_short=cross else cat > conftest.$ac_ext <<EOF -#line 3131 "configure" +#line 3176 "configure" #include "confdefs.h" #include <stdio.h> main() @@ -3138,7 +3183,7 @@ main() exit(0); } EOF -if { (eval echo configure:3142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_short=`cat conftestval` else @@ -3159,12 +3204,12 @@ EOF echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:3163: checking for working const" >&5 +echo "configure:3208: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3168 "configure" +#line 3213 "configure" #include "confdefs.h" int main() { @@ -3213,7 +3258,7 @@ ccp = (char const *const *) p; ; return 0; } EOF -if { (eval echo configure:3217: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3262: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -3234,21 +3279,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:3238: checking for inline" >&5 +echo "configure:3283: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <<EOF -#line 3245 "configure" +#line 3290 "configure" #include "confdefs.h" int main() { } $ac_kw foo() { ; return 0; } EOF -if { (eval echo configure:3252: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3297: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -3274,14 +3319,14 @@ EOF esac echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 -echo "configure:3278: checking whether byte ordering is bigendian" >&5 +echo "configure:3323: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext <<EOF -#line 3285 "configure" +#line 3330 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/param.h> @@ -3292,11 +3337,11 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3296: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3341: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext <<EOF -#line 3300 "configure" +#line 3345 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/param.h> @@ -3307,7 +3352,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3311: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else @@ -3327,7 +3372,7 @@ if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF -#line 3331 "configure" +#line 3376 "configure" #include "confdefs.h" main () { /* Are we little or big endian? From Harbison&Steele. */ @@ -3340,7 +3385,7 @@ main () { exit (u.c[sizeof (long) - 1] == 1); } EOF -if { (eval echo configure:3344: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3389: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no else @@ -3364,14 +3409,14 @@ EOF fi echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6 -echo "configure:3368: checking whether char is unsigned" >&5 +echo "configure:3413: checking whether char is unsigned" >&5 if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. cat > conftest.$ac_ext <<EOF -#line 3375 "configure" +#line 3420 "configure" #include "confdefs.h" #ifdef __CHAR_UNSIGNED__ yes @@ -3393,7 +3438,7 @@ if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF -#line 3397 "configure" +#line 3442 "configure" #include "confdefs.h" /* volatile prevents gcc2 from optimizing the test away on sparcs. */ #if !defined(__STDC__) || __STDC__ != 1 @@ -3403,7 +3448,7 @@ main() { volatile char c = 255; exit(c < 0); } EOF -if { (eval echo configure:3407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_char_unsigned=yes else @@ -3428,12 +3473,12 @@ fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:3432: checking return type of signal handlers" >&5 +echo "configure:3477: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3437 "configure" +#line 3482 "configure" #include "confdefs.h" #include <sys/types.h> #include <signal.h> @@ -3450,7 +3495,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:3454: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3499: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -3469,12 +3514,12 @@ EOF echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:3473: checking for uid_t in sys/types.h" >&5 +echo "configure:3518: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3478 "configure" +#line 3523 "configure" #include "confdefs.h" #include <sys/types.h> EOF @@ -3503,12 +3548,12 @@ EOF fi echo $ac_n "checking for mode_t""... $ac_c" 1>&6 -echo "configure:3507: checking for mode_t" >&5 +echo "configure:3552: checking for mode_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3512 "configure" +#line 3557 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3536,12 +3581,12 @@ EOF fi echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:3540: checking for off_t" >&5 +echo "configure:3585: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3545 "configure" +#line 3590 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3569,12 +3614,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:3573: checking for size_t" >&5 +echo "configure:3618: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3578 "configure" +#line 3623 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3602,12 +3647,12 @@ EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:3606: checking for pid_t" >&5 +echo "configure:3651: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3611 "configure" +#line 3656 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3635,12 +3680,12 @@ EOF fi echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 -echo "configure:3639: checking for st_rdev in struct stat" >&5 +echo "configure:3684: checking for st_rdev in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3644 "configure" +#line 3689 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/stat.h> @@ -3648,7 +3693,7 @@ int main() { struct stat s; s.st_rdev; ; return 0; } EOF -if { (eval echo configure:3652: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3697: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_rdev=yes else @@ -3669,12 +3714,12 @@ EOF fi echo $ac_n "checking for d_off in dirent""... $ac_c" 1>&6 -echo "configure:3673: checking for d_off in dirent" >&5 +echo "configure:3718: checking for d_off in dirent" >&5 if eval "test \"`echo '$''{'ac_cv_dirent_d_off'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3678 "configure" +#line 3723 "configure" #include "confdefs.h" #include <unistd.h> @@ -3684,7 +3729,7 @@ int main() { struct dirent d; d.d_off; ; return 0; } EOF -if { (eval echo configure:3688: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3733: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_dirent_d_off=yes else @@ -3705,12 +3750,12 @@ EOF fi echo $ac_n "checking for ino_t""... $ac_c" 1>&6 -echo "configure:3709: checking for ino_t" >&5 +echo "configure:3754: checking for ino_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ino_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3714 "configure" +#line 3759 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3738,12 +3783,12 @@ EOF fi echo $ac_n "checking for loff_t""... $ac_c" 1>&6 -echo "configure:3742: checking for loff_t" >&5 +echo "configure:3787: checking for loff_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_loff_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3747 "configure" +#line 3792 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3771,12 +3816,12 @@ EOF fi echo $ac_n "checking for offset_t""... $ac_c" 1>&6 -echo "configure:3775: checking for offset_t" >&5 +echo "configure:3820: checking for offset_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_offset_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3780 "configure" +#line 3825 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3804,12 +3849,12 @@ EOF fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:3808: checking for ssize_t" >&5 +echo "configure:3853: checking for ssize_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3813 "configure" +#line 3858 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3837,12 +3882,12 @@ EOF fi echo $ac_n "checking for wchar_t""... $ac_c" 1>&6 -echo "configure:3841: checking for wchar_t" >&5 +echo "configure:3886: checking for wchar_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_wchar_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3846 "configure" +#line 3891 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -3872,7 +3917,7 @@ fi # we need libcups for CUPS support... echo $ac_n "checking for httpConnect in -lcups""... $ac_c" 1>&6 -echo "configure:3876: checking for httpConnect in -lcups" >&5 +echo "configure:3921: checking for httpConnect in -lcups" >&5 ac_lib_var=`echo cups'_'httpConnect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3880,7 +3925,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcups $LIBS" cat > conftest.$ac_ext <<EOF -#line 3884 "configure" +#line 3929 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -3891,7 +3936,7 @@ int main() { httpConnect() ; return 0; } EOF -if { (eval echo configure:3895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3921,7 +3966,7 @@ fi # we need libdl for PAM and the new VFS code echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:3925: checking for dlopen in -ldl" >&5 +echo "configure:3970: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3929,7 +3974,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <<EOF -#line 3933 "configure" +#line 3978 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -3940,7 +3985,7 @@ int main() { dlopen() ; return 0; } EOF -if { (eval echo configure:3944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3989: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3965,14 +4010,54 @@ else fi +echo $ac_n "checking for socklen_t type""... $ac_c" 1>&6 +echo "configure:4015: checking for socklen_t type" >&5 +if eval "test \"`echo '$''{'samba_cv_socklen_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <<EOF +#line 4021 "configure" +#include "confdefs.h" + +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +#include <sys/socket.h> +int main() { +socklen_t i = 0 +; return 0; } +EOF +if { (eval echo configure:4034: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + samba_cv_socklen_t=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + samba_cv_socklen_t=no +fi +rm -f conftest* +fi + +echo "$ac_t""$samba_cv_socklen_t" 1>&6 +if test x"$samba_cv_socklen_t" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SOCKLEN_T_TYPE 1 +EOF + +fi + echo $ac_n "checking for sig_atomic_t type""... $ac_c" 1>&6 -echo "configure:3970: checking for sig_atomic_t type" >&5 +echo "configure:4055: checking for sig_atomic_t type" >&5 if eval "test \"`echo '$''{'samba_cv_sig_atomic_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3976 "configure" +#line 4061 "configure" #include "confdefs.h" #include <sys/types.h> @@ -3985,7 +4070,7 @@ int main() { sig_atomic_t i = 0 ; return 0; } EOF -if { (eval echo configure:3989: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4074: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_sig_atomic_t=yes else @@ -4005,114 +4090,257 @@ EOF fi -echo $ac_n "checking for errno in errno.h""... $ac_c" 1>&6 -echo "configure:4010: checking for errno in errno.h" >&5 -if eval "test \"`echo '$''{'samba_cv_errno'+set}'`\" = set"; then +# stupid headers have the functions but no declaration. grrrr. + + echo $ac_n "checking for errno declaration""... $ac_c" 1>&6 +echo "configure:4097: checking for errno declaration" >&5 +if eval "test \"`echo '$''{'ac_cv_have_errno_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4016 "configure" +#line 4103 "configure" #include "confdefs.h" #include <errno.h> int main() { -int i = errno +int i = (int)errno ; return 0; } EOF -if { (eval echo configure:4023: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4110: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* - samba_cv_errno=yes + ac_cv_have_errno_decl=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - samba_cv_have_errno=no + ac_cv_have_errno_decl=no fi rm -f conftest* fi -echo "$ac_t""$samba_cv_errno" 1>&6 -if test x"$samba_cv_errno" = x"yes"; then - cat >> confdefs.h <<\EOF +echo "$ac_t""$ac_cv_have_errno_decl" 1>&6 + if test x"$ac_cv_have_errno_decl" = x"yes"; then + cat >> confdefs.h <<\EOF #define HAVE_ERRNO_DECL 1 EOF -fi + fi + -# stupid glibc has the functions but no declaration. grrrr. -echo $ac_n "checking for setresuid declaration""... $ac_c" 1>&6 -echo "configure:4045: checking for setresuid declaration" >&5 -if eval "test \"`echo '$''{'samba_cv_have_setresuid_decl'+set}'`\" = set"; then + echo $ac_n "checking for setresuid declaration""... $ac_c" 1>&6 +echo "configure:4132: checking for setresuid declaration" >&5 +if eval "test \"`echo '$''{'ac_cv_have_setresuid_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4051 "configure" +#line 4138 "configure" #include "confdefs.h" #include <unistd.h> int main() { int i = (int)setresuid ; return 0; } EOF -if { (eval echo configure:4058: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* - samba_cv_have_setresuid_decl=yes + ac_cv_have_setresuid_decl=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - samba_cv_have_setresuid_decl=no + ac_cv_have_setresuid_decl=no fi rm -f conftest* fi -echo "$ac_t""$samba_cv_have_setresuid_decl" 1>&6 -if test x"$samba_cv_have_setresuid_decl" = x"yes"; then +echo "$ac_t""$ac_cv_have_setresuid_decl" 1>&6 + if test x"$ac_cv_have_setresuid_decl" = x"yes"; then cat >> confdefs.h <<\EOF #define HAVE_SETRESUID_DECL 1 EOF -fi + fi -# stupid glibc has the functions but no declaration. grrrr. -echo $ac_n "checking for setresgid declaration""... $ac_c" 1>&6 -echo "configure:4080: checking for setresgid declaration" >&5 -if eval "test \"`echo '$''{'samba_cv_have_setresgid_decl'+set}'`\" = set"; then + + echo $ac_n "checking for setresgid declaration""... $ac_c" 1>&6 +echo "configure:4167: checking for setresgid declaration" >&5 +if eval "test \"`echo '$''{'ac_cv_have_setresgid_decl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4086 "configure" +#line 4173 "configure" #include "confdefs.h" #include <unistd.h> int main() { int i = (int)setresgid ; return 0; } EOF -if { (eval echo configure:4093: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4180: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* - samba_cv_have_setresgid_decl=yes + ac_cv_have_setresgid_decl=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - samba_cv_have_setresgid_decl=no + ac_cv_have_setresgid_decl=no fi rm -f conftest* fi -echo "$ac_t""$samba_cv_have_setresgid_decl" 1>&6 -if test x"$samba_cv_have_setresgid_decl" = x"yes"; then +echo "$ac_t""$ac_cv_have_setresgid_decl" 1>&6 + if test x"$ac_cv_have_setresgid_decl" = x"yes"; then cat >> confdefs.h <<\EOF #define HAVE_SETRESGID_DECL 1 EOF + fi + + + echo $ac_n "checking for asprintf declaration""... $ac_c" 1>&6 +echo "configure:4202: checking for asprintf declaration" >&5 +if eval "test \"`echo '$''{'ac_cv_have_asprintf_decl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <<EOF +#line 4208 "configure" +#include "confdefs.h" +#include <stdio.h> +int main() { +int i = (int)asprintf +; return 0; } +EOF +if { (eval echo configure:4215: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_asprintf_decl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_asprintf_decl=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_have_asprintf_decl" 1>&6 + if test x"$ac_cv_have_asprintf_decl" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ASPRINTF_DECL 1 +EOF + + fi + + + echo $ac_n "checking for vasprintf declaration""... $ac_c" 1>&6 +echo "configure:4237: checking for vasprintf declaration" >&5 +if eval "test \"`echo '$''{'ac_cv_have_vasprintf_decl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <<EOF +#line 4243 "configure" +#include "confdefs.h" +#include <stdio.h> +int main() { +int i = (int)vasprintf +; return 0; } +EOF +if { (eval echo configure:4250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_vasprintf_decl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_vasprintf_decl=no +fi +rm -f conftest* fi +echo "$ac_t""$ac_cv_have_vasprintf_decl" 1>&6 + if test x"$ac_cv_have_vasprintf_decl" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_VASPRINTF_DECL 1 +EOF + + fi + + + echo $ac_n "checking for vsnprintf declaration""... $ac_c" 1>&6 +echo "configure:4272: checking for vsnprintf declaration" >&5 +if eval "test \"`echo '$''{'ac_cv_have_vsnprintf_decl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <<EOF +#line 4278 "configure" +#include "confdefs.h" +#include <stdio.h> +int main() { +int i = (int)vsnprintf +; return 0; } +EOF +if { (eval echo configure:4285: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_vsnprintf_decl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_vsnprintf_decl=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_have_vsnprintf_decl" 1>&6 + if test x"$ac_cv_have_vsnprintf_decl" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_VSNPRINTF_DECL 1 +EOF + + fi + + + echo $ac_n "checking for snprintf declaration""... $ac_c" 1>&6 +echo "configure:4307: checking for snprintf declaration" >&5 +if eval "test \"`echo '$''{'ac_cv_have_snprintf_decl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <<EOF +#line 4313 "configure" +#include "confdefs.h" +#include <stdio.h> +int main() { +int i = (int)snprintf +; return 0; } +EOF +if { (eval echo configure:4320: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_snprintf_decl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_snprintf_decl=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_have_snprintf_decl" 1>&6 + if test x"$ac_cv_have_snprintf_decl" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SNPRINTF_DECL 1 +EOF + + fi + + # and glibc has setresuid under linux but the function does # nothing until kernel 2.1.44! very dumb. echo $ac_n "checking for real setresuid""... $ac_c" 1>&6 -echo "configure:4116: checking for real setresuid" >&5 +echo "configure:4344: checking for real setresuid" >&5 if eval "test \"`echo '$''{'samba_cv_have_setresuid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4121,12 +4349,12 @@ else samba_cv_have_setresuid=cross else cat > conftest.$ac_ext <<EOF -#line 4125 "configure" +#line 4353 "configure" #include "confdefs.h" #include <errno.h> main() { setresuid(1,1,1); setresuid(2,2,2); exit(errno==EPERM?0:1);} EOF -if { (eval echo configure:4130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_have_setresuid=yes else @@ -4151,7 +4379,7 @@ fi # Do the same check for setresguid... # echo $ac_n "checking for real setresgid""... $ac_c" 1>&6 -echo "configure:4155: checking for real setresgid" >&5 +echo "configure:4383: checking for real setresgid" >&5 if eval "test \"`echo '$''{'samba_cv_have_setresgid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4160,13 +4388,13 @@ else samba_cv_have_setresgid=cross else cat > conftest.$ac_ext <<EOF -#line 4164 "configure" +#line 4392 "configure" #include "confdefs.h" #include <unistd.h> #include <errno.h> main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);} EOF -if { (eval echo configure:4170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4398: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_have_setresgid=yes else @@ -4189,7 +4417,7 @@ EOF fi echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 -echo "configure:4193: checking for 8-bit clean memcmp" >&5 +echo "configure:4421: checking for 8-bit clean memcmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4197,7 +4425,7 @@ else ac_cv_func_memcmp_clean=no else cat > conftest.$ac_ext <<EOF -#line 4201 "configure" +#line 4429 "configure" #include "confdefs.h" main() @@ -4207,7 +4435,7 @@ main() } EOF -if { (eval echo configure:4211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_memcmp_clean=yes else @@ -4226,116 +4454,12 @@ test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" ############################################### -# test for where we get crypt() from -for ac_func in crypt -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4234: checking for $ac_func" >&5 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 4239 "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func(); below. */ -#include <assert.h> -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:4262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <<EOF -#define $ac_tr_func 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi -done - -if test x"$ac_cv_func_crypt" = x"no"; then - echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:4288: checking for crypt in -lcrypt" >&5 -ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lcrypt $LIBS" -cat > conftest.$ac_ext <<EOF -#line 4296 "configure" -#include "confdefs.h" -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char crypt(); - -int main() { -crypt() -; return 0; } -EOF -if { (eval echo configure:4307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - LIBS="$LIBS -lcrypt"; - cat >> confdefs.h <<\EOF -#define HAVE_CRYPT 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi - -fi - -############################################### # Readline included by default unless explicitly asked not to test "${with_readline+set}" != "set" && with_readline=yes # test for where we get readline() from echo $ac_n "checking whether to use readline""... $ac_c" 1>&6 -echo "configure:4339: checking whether to use readline" >&5 +echo "configure:4463: checking whether to use readline" >&5 # Check whether --with-readline or --without-readline was given. if test "${with_readline+set}" = set; then withval="$with_readline" @@ -4347,17 +4471,17 @@ if test "${with_readline+set}" = set; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4351: checking for $ac_hdr" >&5 +echo "configure:4475: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4356 "configure" +#line 4480 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4361: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4485: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4387,17 +4511,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4391: checking for $ac_hdr" >&5 +echo "configure:4515: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4396 "configure" +#line 4520 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4401: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4525: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4428,17 +4552,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4432: checking for $ac_hdr" >&5 +echo "configure:4556: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4437 "configure" +#line 4561 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4442: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4566: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4461,7 +4585,7 @@ EOF for termlib in ncurses curses termcap terminfo termlib; do echo $ac_n "checking for tgetent in -l${termlib}""... $ac_c" 1>&6 -echo "configure:4465: checking for tgetent in -l${termlib}" >&5 +echo "configure:4589: checking for tgetent in -l${termlib}" >&5 ac_lib_var=`echo ${termlib}'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4469,7 +4593,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${termlib} $LIBS" cat > conftest.$ac_ext <<EOF -#line 4473 "configure" +#line 4597 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -4480,7 +4604,7 @@ int main() { tgetent() ; return 0; } EOF -if { (eval echo configure:4484: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4608: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4502,7 +4626,7 @@ fi done echo $ac_n "checking for rl_callback_handler_install in -lreadline""... $ac_c" 1>&6 -echo "configure:4506: checking for rl_callback_handler_install in -lreadline" >&5 +echo "configure:4630: checking for rl_callback_handler_install in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_callback_handler_install | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4510,7 +4634,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $TERMLIBS $LIBS" cat > conftest.$ac_ext <<EOF -#line 4514 "configure" +#line 4638 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -4521,7 +4645,7 @@ int main() { rl_callback_handler_install() ; return 0; } EOF -if { (eval echo configure:4525: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4649: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4572,17 +4696,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4576: checking for $ac_hdr" >&5 +echo "configure:4700: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4581 "configure" +#line 4705 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4710: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4612,17 +4736,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4616: checking for $ac_hdr" >&5 +echo "configure:4740: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4621 "configure" +#line 4745 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4750: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4653,17 +4777,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4657: checking for $ac_hdr" >&5 +echo "configure:4781: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4662 "configure" +#line 4786 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4667: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4791: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4686,7 +4810,7 @@ EOF for termlib in ncurses curses termcap terminfo termlib; do echo $ac_n "checking for tgetent in -l${termlib}""... $ac_c" 1>&6 -echo "configure:4690: checking for tgetent in -l${termlib}" >&5 +echo "configure:4814: checking for tgetent in -l${termlib}" >&5 ac_lib_var=`echo ${termlib}'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4694,7 +4818,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${termlib} $LIBS" cat > conftest.$ac_ext <<EOF -#line 4698 "configure" +#line 4822 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -4705,7 +4829,7 @@ int main() { tgetent() ; return 0; } EOF -if { (eval echo configure:4709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4727,7 +4851,7 @@ fi done echo $ac_n "checking for rl_callback_handler_install in -lreadline""... $ac_c" 1>&6 -echo "configure:4731: checking for rl_callback_handler_install in -lreadline" >&5 +echo "configure:4855: checking for rl_callback_handler_install in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_callback_handler_install | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4735,7 +4859,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $TERMLIBS $LIBS" cat > conftest.$ac_ext <<EOF -#line 4739 "configure" +#line 4863 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -4746,7 +4870,7 @@ int main() { rl_callback_handler_install() ; return 0; } EOF -if { (eval echo configure:4750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4801,12 +4925,12 @@ fi for ac_func in connect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4805: checking for $ac_func" >&5 +echo "configure:4929: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 4810 "configure" +#line 4934 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -4829,7 +4953,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:4833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4857,7 +4981,7 @@ if test x"$ac_cv_func_connect" = x"no"; then case "$LIBS" in *-lnsl*) ;; *) echo $ac_n "checking for printf in -lnsl_s""... $ac_c" 1>&6 -echo "configure:4861: checking for printf in -lnsl_s" >&5 +echo "configure:4985: checking for printf in -lnsl_s" >&5 ac_lib_var=`echo nsl_s'_'printf | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4865,7 +4989,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl_s $LIBS" cat > conftest.$ac_ext <<EOF -#line 4869 "configure" +#line 4993 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -4876,7 +5000,7 @@ int main() { printf() ; return 0; } EOF -if { (eval echo configure:4880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4907,7 +5031,7 @@ fi case "$LIBS" in *-lnsl*) ;; *) echo $ac_n "checking for printf in -lnsl""... $ac_c" 1>&6 -echo "configure:4911: checking for printf in -lnsl" >&5 +echo "configure:5035: checking for printf in -lnsl" >&5 ac_lib_var=`echo nsl'_'printf | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4915,7 +5039,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <<EOF -#line 4919 "configure" +#line 5043 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -4926,7 +5050,7 @@ int main() { printf() ; return 0; } EOF -if { (eval echo configure:4930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4957,7 +5081,7 @@ fi case "$LIBS" in *-lsocket*) ;; *) echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 -echo "configure:4961: checking for connect in -lsocket" >&5 +echo "configure:5085: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4965,7 +5089,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <<EOF -#line 4969 "configure" +#line 5093 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -4976,7 +5100,7 @@ int main() { connect() ; return 0; } EOF -if { (eval echo configure:4980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5007,7 +5131,7 @@ fi case "$LIBS" in *-linet*) ;; *) echo $ac_n "checking for connect in -linet""... $ac_c" 1>&6 -echo "configure:5011: checking for connect in -linet" >&5 +echo "configure:5135: checking for connect in -linet" >&5 ac_lib_var=`echo inet'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5015,7 +5139,7 @@ else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF -#line 5019 "configure" +#line 5143 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -5026,7 +5150,7 @@ int main() { connect() ; return 0; } EOF -if { (eval echo configure:5030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5154: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5070,12 +5194,12 @@ fi for ac_func in yp_get_default_domain do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5074: checking for $ac_func" >&5 +echo "configure:5198: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5079 "configure" +#line 5203 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5098,7 +5222,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5124,7 +5248,7 @@ done if test x"$ac_cv_func_yp_get_default_domain" = x"no"; then echo $ac_n "checking for yp_get_default_domain in -lnsl""... $ac_c" 1>&6 -echo "configure:5128: checking for yp_get_default_domain in -lnsl" >&5 +echo "configure:5252: checking for yp_get_default_domain in -lnsl" >&5 ac_lib_var=`echo nsl'_'yp_get_default_domain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5132,7 +5256,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <<EOF -#line 5136 "configure" +#line 5260 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -5143,7 +5267,7 @@ int main() { yp_get_default_domain() ; return 0; } EOF -if { (eval echo configure:5147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5271: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5173,12 +5297,12 @@ fi for ac_func in execl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5177: checking for $ac_func" >&5 +echo "configure:5301: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5182 "configure" +#line 5306 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5201,7 +5325,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5329: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5234,12 +5358,12 @@ fi for ac_func in waitpid getcwd strdup strtoul strerror chown fchown chmod fchmod chroot do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5238: checking for $ac_func" >&5 +echo "configure:5362: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5243 "configure" +#line 5367 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5262,7 +5386,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5289,12 +5413,12 @@ done for ac_func in fstat strchr utime utimes getrlimit fsync bzero memset do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5293: checking for $ac_func" >&5 +echo "configure:5417: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5298 "configure" +#line 5422 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5317,7 +5441,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5341,15 +5465,15 @@ else fi done -for ac_func in memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid +for ac_func in memmove vsnprintf snprintf asprintf vasprintf setsid glob strpbrk pipe crypt16 getauthuid do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5348: checking for $ac_func" >&5 +echo "configure:5472: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5353 "configure" +#line 5477 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5372,7 +5496,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5376: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5399,12 +5523,12 @@ done for ac_func in strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5403: checking for $ac_func" >&5 +echo "configure:5527: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5408 "configure" +#line 5532 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5427,7 +5551,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5454,12 +5578,12 @@ done for ac_func in initgroups select poll rdchk getgrnam getgrent pathconf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5458: checking for $ac_func" >&5 +echo "configure:5582: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5463 "configure" +#line 5587 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5482,7 +5606,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5509,12 +5633,12 @@ done for ac_func in setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5513: checking for $ac_func" >&5 +echo "configure:5637: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5518 "configure" +#line 5642 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5537,7 +5661,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5564,12 +5688,12 @@ done for ac_func in lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5568: checking for $ac_func" >&5 +echo "configure:5692: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5573 "configure" +#line 5697 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5592,7 +5716,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5619,12 +5743,12 @@ done for ac_func in fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5623: checking for $ac_func" >&5 +echo "configure:5747: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5628 "configure" +#line 5752 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5647,7 +5771,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5671,15 +5795,15 @@ else fi done -for ac_func in srandom random srand rand setenv usleep strcasecmp fcvt fcvtl +for ac_func in srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5678: checking for $ac_func" >&5 +echo "configure:5802: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5683 "configure" +#line 5807 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5702,7 +5826,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5706: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5731,12 +5855,12 @@ done for ac_func in syscall do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5735: checking for $ac_func" >&5 +echo "configure:5859: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5740 "configure" +#line 5864 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5759,7 +5883,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5787,12 +5911,12 @@ done for ac_func in _dup _dup2 _opendir _readdir _seekdir _telldir _closedir do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5791: checking for $ac_func" >&5 +echo "configure:5915: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5796 "configure" +#line 5920 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5815,7 +5939,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5842,12 +5966,12 @@ done for ac_func in __dup __dup2 __opendir __readdir __seekdir __telldir __closedir do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5846: checking for $ac_func" >&5 +echo "configure:5970: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5851 "configure" +#line 5975 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5870,7 +5994,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5897,12 +6021,12 @@ done for ac_func in __getcwd _getcwd do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5901: checking for $ac_func" >&5 +echo "configure:6025: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5906 "configure" +#line 6030 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5925,7 +6049,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5952,12 +6076,12 @@ done for ac_func in __xstat __fxstat __lxstat do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5956: checking for $ac_func" >&5 +echo "configure:6080: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5961 "configure" +#line 6085 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -5980,7 +6104,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:5984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6007,12 +6131,12 @@ done for ac_func in _stat _lstat _fstat __stat __lstat __fstat do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6011: checking for $ac_func" >&5 +echo "configure:6135: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6016 "configure" +#line 6140 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6035,7 +6159,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6163: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6062,12 +6186,12 @@ done for ac_func in _acl __acl _facl __facl _open __open _chdir __chdir do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6066: checking for $ac_func" >&5 +echo "configure:6190: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6071 "configure" +#line 6195 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6090,7 +6214,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6117,12 +6241,12 @@ done for ac_func in _close __close _fchdir __fchdir _fcntl __fcntl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6121: checking for $ac_func" >&5 +echo "configure:6245: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6126 "configure" +#line 6250 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6145,7 +6269,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6149: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6172,12 +6296,12 @@ done for ac_func in getdents _getdents __getdents _lseek __lseek _read __read do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6176: checking for $ac_func" >&5 +echo "configure:6300: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6181 "configure" +#line 6305 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6200,7 +6324,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6204: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6328: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6227,12 +6351,12 @@ done for ac_func in _write __write _fork __fork do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6231: checking for $ac_func" >&5 +echo "configure:6355: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6236 "configure" +#line 6360 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6255,7 +6379,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6282,12 +6406,12 @@ done for ac_func in _stat64 __stat64 _fstat64 __fstat64 _lstat64 __lstat64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6286: checking for $ac_func" >&5 +echo "configure:6410: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6291 "configure" +#line 6415 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6310,7 +6434,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6314: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6337,12 +6461,12 @@ done for ac_func in __sys_llseek llseek _llseek __llseek readdir64 _readdir64 __readdir64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6341: checking for $ac_func" >&5 +echo "configure:6465: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6346 "configure" +#line 6470 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6365,7 +6489,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6392,12 +6516,12 @@ done for ac_func in pread _pread __pread pread64 _pread64 __pread64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6396: checking for $ac_func" >&5 +echo "configure:6520: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6401 "configure" +#line 6525 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6420,7 +6544,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6447,12 +6571,12 @@ done for ac_func in pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6451: checking for $ac_func" >&5 +echo "configure:6575: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6456 "configure" +#line 6580 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6475,7 +6599,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6502,12 +6626,12 @@ done for ac_func in open64 _open64 __open64 creat64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6506: checking for $ac_func" >&5 +echo "configure:6630: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6511 "configure" +#line 6635 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6530,7 +6654,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6561,9 +6685,9 @@ done if test x$ac_cv_func_stat64 = xno ; then echo $ac_n "checking for stat64 in <sys/stat.h>""... $ac_c" 1>&6 -echo "configure:6565: checking for stat64 in <sys/stat.h>" >&5 +echo "configure:6689: checking for stat64 in <sys/stat.h>" >&5 cat > conftest.$ac_ext <<EOF -#line 6567 "configure" +#line 6691 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -6575,7 +6699,7 @@ int main() { struct stat64 st64; exit(stat64(".",&st64)); ; return 0; } EOF -if { (eval echo configure:6579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6703: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_stat64=yes else @@ -6594,9 +6718,9 @@ fi if test x$ac_cv_func_lstat64 = xno ; then echo $ac_n "checking for lstat64 in <sys/stat.h>""... $ac_c" 1>&6 -echo "configure:6598: checking for lstat64 in <sys/stat.h>" >&5 +echo "configure:6722: checking for lstat64 in <sys/stat.h>" >&5 cat > conftest.$ac_ext <<EOF -#line 6600 "configure" +#line 6724 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -6608,7 +6732,7 @@ int main() { struct stat64 st64; exit(lstat64(".",&st64)); ; return 0; } EOF -if { (eval echo configure:6612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_lstat64=yes else @@ -6627,9 +6751,9 @@ fi if test x$ac_cv_func_fstat64 = xno ; then echo $ac_n "checking for fstat64 in <sys/stat.h>""... $ac_c" 1>&6 -echo "configure:6631: checking for fstat64 in <sys/stat.h>" >&5 +echo "configure:6755: checking for fstat64 in <sys/stat.h>" >&5 cat > conftest.$ac_ext <<EOF -#line 6633 "configure" +#line 6757 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -6641,7 +6765,7 @@ int main() { struct stat64 st64; exit(fstat64(0,&st64)); ; return 0; } EOF -if { (eval echo configure:6645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_fstat64=yes else @@ -6666,7 +6790,7 @@ fi if test x$ac_cv_func_strcasecmp = xno ; then echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6 -echo "configure:6670: checking for strcasecmp in -lresolv" >&5 +echo "configure:6794: checking for strcasecmp in -lresolv" >&5 ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6674,7 +6798,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <<EOF -#line 6678 "configure" +#line 6802 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -6685,7 +6809,7 @@ int main() { strcasecmp() ; return 0; } EOF -if { (eval echo configure:6689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6721,12 +6845,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6725: checking for $ac_func" >&5 +echo "configure:6849: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6730 "configure" +#line 6854 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6749,7 +6873,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6753: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6774,7 +6898,7 @@ fi done ;; *) echo $ac_n "checking for putprpwnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:6778: checking for putprpwnam in -lsecurity" >&5 +echo "configure:6902: checking for putprpwnam in -lsecurity" >&5 ac_lib_var=`echo security'_'putprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6782,7 +6906,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <<EOF -#line 6786 "configure" +#line 6910 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -6793,7 +6917,7 @@ int main() { putprpwnam() ; return 0; } EOF -if { (eval echo configure:6797: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6921: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6823,12 +6947,12 @@ fi for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6827: checking for $ac_func" >&5 +echo "configure:6951: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6832 "configure" +#line 6956 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6851,7 +6975,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6979: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6882,12 +7006,12 @@ case "$LIBS" in *-lsec*) for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6886: checking for $ac_func" >&5 +echo "configure:7010: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6891 "configure" +#line 7015 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6910,7 +7034,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6935,7 +7059,7 @@ fi done ;; *) echo $ac_n "checking for putprpwnam in -lsec""... $ac_c" 1>&6 -echo "configure:6939: checking for putprpwnam in -lsec" >&5 +echo "configure:7063: checking for putprpwnam in -lsec" >&5 ac_lib_var=`echo sec'_'putprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6943,7 +7067,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <<EOF -#line 6947 "configure" +#line 7071 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -6954,7 +7078,7 @@ int main() { putprpwnam() ; return 0; } EOF -if { (eval echo configure:6958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6984,12 +7108,12 @@ fi for ac_func in putprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6988: checking for $ac_func" >&5 +echo "configure:7112: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6993 "configure" +#line 7117 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7012,7 +7136,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7140: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7044,12 +7168,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7048: checking for $ac_func" >&5 +echo "configure:7172: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7053 "configure" +#line 7177 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7072,7 +7196,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7200: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7097,7 +7221,7 @@ fi done ;; *) echo $ac_n "checking for set_auth_parameters in -lsecurity""... $ac_c" 1>&6 -echo "configure:7101: checking for set_auth_parameters in -lsecurity" >&5 +echo "configure:7225: checking for set_auth_parameters in -lsecurity" >&5 ac_lib_var=`echo security'_'set_auth_parameters | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7105,7 +7229,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <<EOF -#line 7109 "configure" +#line 7233 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -7116,7 +7240,7 @@ int main() { set_auth_parameters() ; return 0; } EOF -if { (eval echo configure:7120: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7244: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7146,12 +7270,12 @@ fi for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7150: checking for $ac_func" >&5 +echo "configure:7274: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7155 "configure" +#line 7279 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7174,7 +7298,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7205,12 +7329,12 @@ case "$LIBS" in *-lsec*) for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7209: checking for $ac_func" >&5 +echo "configure:7333: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7214 "configure" +#line 7338 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7233,7 +7357,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7361: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7258,7 +7382,7 @@ fi done ;; *) echo $ac_n "checking for set_auth_parameters in -lsec""... $ac_c" 1>&6 -echo "configure:7262: checking for set_auth_parameters in -lsec" >&5 +echo "configure:7386: checking for set_auth_parameters in -lsec" >&5 ac_lib_var=`echo sec'_'set_auth_parameters | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7266,7 +7390,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <<EOF -#line 7270 "configure" +#line 7394 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -7277,7 +7401,7 @@ int main() { set_auth_parameters() ; return 0; } EOF -if { (eval echo configure:7281: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7307,12 +7431,12 @@ fi for ac_func in set_auth_parameters do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7311: checking for $ac_func" >&5 +echo "configure:7435: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7316 "configure" +#line 7440 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7335,7 +7459,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7463: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7368,12 +7492,12 @@ case "$LIBS" in *-lgen*) for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7372: checking for $ac_func" >&5 +echo "configure:7496: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7377 "configure" +#line 7501 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7396,7 +7520,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7421,7 +7545,7 @@ fi done ;; *) echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6 -echo "configure:7425: checking for getspnam in -lgen" >&5 +echo "configure:7549: checking for getspnam in -lgen" >&5 ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7429,7 +7553,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgen $LIBS" cat > conftest.$ac_ext <<EOF -#line 7433 "configure" +#line 7557 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -7440,7 +7564,7 @@ int main() { getspnam() ; return 0; } EOF -if { (eval echo configure:7444: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7470,12 +7594,12 @@ fi for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7474: checking for $ac_func" >&5 +echo "configure:7598: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7479 "configure" +#line 7603 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7498,7 +7622,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7502: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7530,12 +7654,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7534: checking for $ac_func" >&5 +echo "configure:7658: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7539 "configure" +#line 7663 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7558,7 +7682,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7686: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7583,7 +7707,7 @@ fi done ;; *) echo $ac_n "checking for getspnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:7587: checking for getspnam in -lsecurity" >&5 +echo "configure:7711: checking for getspnam in -lsecurity" >&5 ac_lib_var=`echo security'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7591,7 +7715,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <<EOF -#line 7595 "configure" +#line 7719 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -7602,7 +7726,7 @@ int main() { getspnam() ; return 0; } EOF -if { (eval echo configure:7606: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7632,12 +7756,12 @@ fi for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7636: checking for $ac_func" >&5 +echo "configure:7760: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7641 "configure" +#line 7765 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7660,7 +7784,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7788: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7691,12 +7815,12 @@ case "$LIBS" in *-lsec*) for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7695: checking for $ac_func" >&5 +echo "configure:7819: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7700 "configure" +#line 7824 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7719,7 +7843,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7744,7 +7868,7 @@ fi done ;; *) echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6 -echo "configure:7748: checking for getspnam in -lsec" >&5 +echo "configure:7872: checking for getspnam in -lsec" >&5 ac_lib_var=`echo sec'_'getspnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7752,7 +7876,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <<EOF -#line 7756 "configure" +#line 7880 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -7763,7 +7887,7 @@ int main() { getspnam() ; return 0; } EOF -if { (eval echo configure:7767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7793,12 +7917,12 @@ fi for ac_func in getspnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7797: checking for $ac_func" >&5 +echo "configure:7921: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7802 "configure" +#line 7926 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7821,7 +7945,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7853,12 +7977,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7857: checking for $ac_func" >&5 +echo "configure:7981: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7862 "configure" +#line 7986 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7881,7 +8005,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8009: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7906,7 +8030,7 @@ fi done ;; *) echo $ac_n "checking for bigcrypt in -lsecurity""... $ac_c" 1>&6 -echo "configure:7910: checking for bigcrypt in -lsecurity" >&5 +echo "configure:8034: checking for bigcrypt in -lsecurity" >&5 ac_lib_var=`echo security'_'bigcrypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7914,7 +8038,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <<EOF -#line 7918 "configure" +#line 8042 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -7925,7 +8049,7 @@ int main() { bigcrypt() ; return 0; } EOF -if { (eval echo configure:7929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7955,12 +8079,12 @@ fi for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7959: checking for $ac_func" >&5 +echo "configure:8083: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7964 "configure" +#line 8088 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7983,7 +8107,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8014,12 +8138,12 @@ case "$LIBS" in *-lsec*) for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8018: checking for $ac_func" >&5 +echo "configure:8142: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8023 "configure" +#line 8147 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -8042,7 +8166,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:8046: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8067,7 +8191,7 @@ fi done ;; *) echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6 -echo "configure:8071: checking for bigcrypt in -lsec" >&5 +echo "configure:8195: checking for bigcrypt in -lsec" >&5 ac_lib_var=`echo sec'_'bigcrypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8075,7 +8199,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <<EOF -#line 8079 "configure" +#line 8203 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -8086,7 +8210,7 @@ int main() { bigcrypt() ; return 0; } EOF -if { (eval echo configure:8090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8116,12 +8240,12 @@ fi for ac_func in bigcrypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8120: checking for $ac_func" >&5 +echo "configure:8244: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8125 "configure" +#line 8249 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -8144,7 +8268,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:8148: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8176,12 +8300,12 @@ case "$LIBS" in *-lsecurity*) for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8180: checking for $ac_func" >&5 +echo "configure:8304: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8185 "configure" +#line 8309 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -8204,7 +8328,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:8208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8229,7 +8353,7 @@ fi done ;; *) echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6 -echo "configure:8233: checking for getprpwnam in -lsecurity" >&5 +echo "configure:8357: checking for getprpwnam in -lsecurity" >&5 ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8237,7 +8361,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsecurity $LIBS" cat > conftest.$ac_ext <<EOF -#line 8241 "configure" +#line 8365 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -8248,7 +8372,7 @@ int main() { getprpwnam() ; return 0; } EOF -if { (eval echo configure:8252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8376: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8278,12 +8402,12 @@ fi for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8282: checking for $ac_func" >&5 +echo "configure:8406: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8287 "configure" +#line 8411 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -8306,7 +8430,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:8310: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8337,12 +8461,12 @@ case "$LIBS" in *-lsec*) for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8341: checking for $ac_func" >&5 +echo "configure:8465: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8346 "configure" +#line 8470 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -8365,7 +8489,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:8369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8390,7 +8514,7 @@ fi done ;; *) echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6 -echo "configure:8394: checking for getprpwnam in -lsec" >&5 +echo "configure:8518: checking for getprpwnam in -lsec" >&5 ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8398,7 +8522,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsec $LIBS" cat > conftest.$ac_ext <<EOF -#line 8402 "configure" +#line 8526 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -8409,7 +8533,7 @@ int main() { getprpwnam() ; return 0; } EOF -if { (eval echo configure:8413: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8439,12 +8563,12 @@ fi for ac_func in getprpwnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8443: checking for $ac_func" >&5 +echo "configure:8567: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8448 "configure" +#line 8572 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -8467,7 +8591,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:8471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8572,7 +8696,7 @@ EOF *dgux*) # Extract the first word of "groff", so it can be a program name with args. set dummy groff; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8576: checking for $ac_word" >&5 +echo "configure:8700: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_ROFF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8627,7 +8751,7 @@ esac # try to work out how to produce pic code with this compiler echo $ac_n "checking whether ${CC-cc} accepts -fpic""... $ac_c" 1>&6 -echo "configure:8631: checking whether ${CC-cc} accepts -fpic" >&5 +echo "configure:8755: checking whether ${CC-cc} accepts -fpic" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_fpic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8647,7 +8771,7 @@ if test $ac_cv_prog_cc_fpic = yes; then fi if test x$PICFLAG = x; then echo $ac_n "checking whether ${CC-cc} accepts -KPIC""... $ac_c" 1>&6 -echo "configure:8651: checking whether ${CC-cc} accepts -KPIC" >&5 +echo "configure:8775: checking whether ${CC-cc} accepts -KPIC" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_KPIC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8668,7 +8792,7 @@ echo "$ac_t""$ac_cv_prog_cc_KPIC" 1>&6 fi if test x$PICFLAG = x; then echo $ac_n "checking whether ${CC-cc} accepts -Kpic""... $ac_c" 1>&6 -echo "configure:8672: checking whether ${CC-cc} accepts -Kpic" >&5 +echo "configure:8796: checking whether ${CC-cc} accepts -Kpic" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_Kpic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8691,7 +8815,7 @@ fi ################ echo $ac_n "checking for long long""... $ac_c" 1>&6 -echo "configure:8695: checking for long long" >&5 +echo "configure:8819: checking for long long" >&5 if eval "test \"`echo '$''{'samba_cv_have_longlong'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8700,12 +8824,12 @@ if test "$cross_compiling" = yes; then samba_cv_have_longlong=cross else cat > conftest.$ac_ext <<EOF -#line 8704 "configure" +#line 8828 "configure" #include "confdefs.h" #include <stdio.h> main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); } EOF -if { (eval echo configure:8709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_have_longlong=yes else @@ -8732,20 +8856,20 @@ fi # AIX needs this. echo $ac_n "checking for LL suffix on long long integers""... $ac_c" 1>&6 -echo "configure:8736: checking for LL suffix on long long integers" >&5 +echo "configure:8860: checking for LL suffix on long long integers" >&5 if eval "test \"`echo '$''{'samba_cv_compiler_supports_ll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8742 "configure" +#line 8866 "configure" #include "confdefs.h" #include <stdio.h> int main() { long long i = 0x8000000000LL ; return 0; } EOF -if { (eval echo configure:8749: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8873: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_compiler_supports_ll=yes else @@ -8767,7 +8891,7 @@ fi echo $ac_n "checking for 64 bit off_t""... $ac_c" 1>&6 -echo "configure:8771: checking for 64 bit off_t" >&5 +echo "configure:8895: checking for 64 bit off_t" >&5 if eval "test \"`echo '$''{'samba_cv_SIZEOF_OFF_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8776,13 +8900,13 @@ if test "$cross_compiling" = yes; then samba_cv_SIZEOF_OFF_T=cross else cat > conftest.$ac_ext <<EOF -#line 8780 "configure" +#line 8904 "configure" #include "confdefs.h" #include <stdio.h> #include <sys/stat.h> main() { exit((sizeof(off_t) == 8) ? 0 : 1); } EOF -if { (eval echo configure:8786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8910: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_SIZEOF_OFF_T=yes else @@ -8805,7 +8929,7 @@ EOF fi echo $ac_n "checking for off64_t""... $ac_c" 1>&6 -echo "configure:8809: checking for off64_t" >&5 +echo "configure:8933: checking for off64_t" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_OFF64_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8814,7 +8938,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_OFF64_T=cross else cat > conftest.$ac_ext <<EOF -#line 8818 "configure" +#line 8942 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -8824,7 +8948,7 @@ else #include <sys/stat.h> main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); } EOF -if { (eval echo configure:8828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8952: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_OFF64_T=yes else @@ -8847,7 +8971,7 @@ EOF fi echo $ac_n "checking for 64 bit ino_t""... $ac_c" 1>&6 -echo "configure:8851: checking for 64 bit ino_t" >&5 +echo "configure:8975: checking for 64 bit ino_t" >&5 if eval "test \"`echo '$''{'samba_cv_SIZEOF_INO_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8856,13 +8980,13 @@ if test "$cross_compiling" = yes; then samba_cv_SIZEOF_INO_T=cross else cat > conftest.$ac_ext <<EOF -#line 8860 "configure" +#line 8984 "configure" #include "confdefs.h" #include <stdio.h> #include <sys/stat.h> main() { exit((sizeof(ino_t) == 8) ? 0 : 1); } EOF -if { (eval echo configure:8866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_SIZEOF_INO_T=yes else @@ -8885,7 +9009,7 @@ EOF fi echo $ac_n "checking for ino64_t""... $ac_c" 1>&6 -echo "configure:8889: checking for ino64_t" >&5 +echo "configure:9013: checking for ino64_t" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_INO64_T'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8894,7 +9018,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_INO64_T=cross else cat > conftest.$ac_ext <<EOF -#line 8898 "configure" +#line 9022 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -8904,7 +9028,7 @@ else #include <sys/stat.h> main() { struct stat64 st; ino64_t s; if (sizeof(ino_t) == sizeof(ino64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); } EOF -if { (eval echo configure:8908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_INO64_T=yes else @@ -8927,13 +9051,13 @@ EOF fi echo $ac_n "checking for struct dirent64""... $ac_c" 1>&6 -echo "configure:8931: checking for struct dirent64" >&5 +echo "configure:9055: checking for struct dirent64" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_DIRENT64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 8937 "configure" +#line 9061 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -8945,7 +9069,7 @@ int main() { struct dirent64 de; ; return 0; } EOF -if { (eval echo configure:8949: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_STRUCT_DIRENT64=yes else @@ -8966,7 +9090,7 @@ EOF fi echo $ac_n "checking for unsigned char""... $ac_c" 1>&6 -echo "configure:8970: checking for unsigned char" >&5 +echo "configure:9094: checking for unsigned char" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UNSIGNED_CHAR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8975,12 +9099,12 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_UNSIGNED_CHAR=cross else cat > conftest.$ac_ext <<EOF -#line 8979 "configure" +#line 9103 "configure" #include "confdefs.h" #include <stdio.h> main() { char c; c=250; exit((c > 0)?0:1); } EOF -if { (eval echo configure:8984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_UNSIGNED_CHAR=yes else @@ -9003,13 +9127,13 @@ EOF fi echo $ac_n "checking for sin_len in sock""... $ac_c" 1>&6 -echo "configure:9007: checking for sin_len in sock" >&5 +echo "configure:9131: checking for sin_len in sock" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_SOCK_SIN_LEN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9013 "configure" +#line 9137 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/socket.h> @@ -9018,7 +9142,7 @@ int main() { struct sockaddr_in sock; sock.sin_len = sizeof(sock); ; return 0; } EOF -if { (eval echo configure:9022: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9146: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_SOCK_SIN_LEN=yes else @@ -9039,13 +9163,13 @@ EOF fi echo $ac_n "checking whether seekdir returns void""... $ac_c" 1>&6 -echo "configure:9043: checking whether seekdir returns void" >&5 +echo "configure:9167: checking whether seekdir returns void" >&5 if eval "test \"`echo '$''{'samba_cv_SEEKDIR_RETURNS_VOID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9049 "configure" +#line 9173 "configure" #include "confdefs.h" #include <sys/types.h> #include <dirent.h> @@ -9054,7 +9178,7 @@ int main() { return 0; ; return 0; } EOF -if { (eval echo configure:9058: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9182: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_SEEKDIR_RETURNS_VOID=yes else @@ -9075,20 +9199,20 @@ EOF fi echo $ac_n "checking for __FILE__ macro""... $ac_c" 1>&6 -echo "configure:9079: checking for __FILE__ macro" >&5 +echo "configure:9203: checking for __FILE__ macro" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FILE_MACRO'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9085 "configure" +#line 9209 "configure" #include "confdefs.h" #include <stdio.h> int main() { printf("%s\n", __FILE__); ; return 0; } EOF -if { (eval echo configure:9092: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9216: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_FILE_MACRO=yes else @@ -9109,20 +9233,20 @@ EOF fi echo $ac_n "checking for __FUNCTION__ macro""... $ac_c" 1>&6 -echo "configure:9113: checking for __FUNCTION__ macro" >&5 +echo "configure:9237: checking for __FUNCTION__ macro" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FUNCTION_MACRO'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9119 "configure" +#line 9243 "configure" #include "confdefs.h" #include <stdio.h> int main() { printf("%s\n", __FUNCTION__); ; return 0; } EOF -if { (eval echo configure:9126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_FUNCTION_MACRO=yes else @@ -9143,7 +9267,7 @@ EOF fi echo $ac_n "checking if gettimeofday takes tz argument""... $ac_c" 1>&6 -echo "configure:9147: checking if gettimeofday takes tz argument" >&5 +echo "configure:9271: checking if gettimeofday takes tz argument" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_GETTIMEOFDAY_TZ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9152,14 +9276,14 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_GETTIMEOFDAY_TZ=cross else cat > conftest.$ac_ext <<EOF -#line 9156 "configure" +#line 9280 "configure" #include "confdefs.h" #include <sys/time.h> #include <unistd.h> main() { struct timeval tv; exit(gettimeofday(&tv, NULL));} EOF -if { (eval echo configure:9163: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_GETTIMEOFDAY_TZ=yes else @@ -9181,9 +9305,62 @@ EOF fi +echo $ac_n "checking for C99 vsnprintf""... $ac_c" 1>&6 +echo "configure:9310: checking for C99 vsnprintf" >&5 +if eval "test \"`echo '$''{'samba_cv_HAVE_C99_VSNPRINTF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +if test "$cross_compiling" = yes; then + samba_cv_HAVE_C99_VSNPRINTF=cross +else + cat > conftest.$ac_ext <<EOF +#line 9319 "configure" +#include "confdefs.h" + +#include <sys/types.h> +#include <stdarg.h> +void foo(const char *format, ...) { + va_list ap; + int len; + char buf[5]; + + va_start(ap, format); + len = vsnprintf(0, 0, format, ap); + va_end(ap); + if (len != 5) exit(1); + + if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1); + + exit(0); +} +main() { foo("hello"); } + +EOF +if { (eval echo configure:9341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + samba_cv_HAVE_C99_VSNPRINTF=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + samba_cv_HAVE_C99_VSNPRINTF=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$samba_cv_HAVE_C99_VSNPRINTF" 1>&6 +if test x"$samba_cv_HAVE_C99_VSNPRINTF" = x"yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_C99_VSNPRINTF 1 +EOF + +fi echo $ac_n "checking for broken readdir""... $ac_c" 1>&6 -echo "configure:9187: checking for broken readdir" >&5 +echo "configure:9364: checking for broken readdir" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_READDIR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9192,7 +9369,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_BROKEN_READDIR=cross else cat > conftest.$ac_ext <<EOF -#line 9196 "configure" +#line 9373 "configure" #include "confdefs.h" #include <sys/types.h> #include <dirent.h> @@ -9200,7 +9377,7 @@ main() { struct dirent *di; DIR *d = opendir("."); di = readdir(d); if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 && di->d_name[0] == 0) exit(0); exit(1);} EOF -if { (eval echo configure:9204: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9381: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_BROKEN_READDIR=yes else @@ -9223,13 +9400,13 @@ EOF fi echo $ac_n "checking for utimbuf""... $ac_c" 1>&6 -echo "configure:9227: checking for utimbuf" >&5 +echo "configure:9404: checking for utimbuf" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UTIMBUF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9233 "configure" +#line 9410 "configure" #include "confdefs.h" #include <sys/types.h> #include <utime.h> @@ -9237,7 +9414,7 @@ int main() { struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf)); ; return 0; } EOF -if { (eval echo configure:9241: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UTIMBUF=yes else @@ -9261,12 +9438,12 @@ fi for ac_func in pututline pututxline updwtmp updwtmpx getutmpx do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9265: checking for $ac_func" >&5 +echo "configure:9442: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9270 "configure" +#line 9447 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -9289,7 +9466,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:9293: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9315,13 +9492,13 @@ done echo $ac_n "checking for ut_name in utmp""... $ac_c" 1>&6 -echo "configure:9319: checking for ut_name in utmp" >&5 +echo "configure:9496: checking for ut_name in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_NAME'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9325 "configure" +#line 9502 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9329,7 +9506,7 @@ int main() { struct utmp ut; ut.ut_name[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:9333: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9510: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_NAME=yes else @@ -9350,13 +9527,13 @@ EOF fi echo $ac_n "checking for ut_user in utmp""... $ac_c" 1>&6 -echo "configure:9354: checking for ut_user in utmp" >&5 +echo "configure:9531: checking for ut_user in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_USER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9360 "configure" +#line 9537 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9364,7 +9541,7 @@ int main() { struct utmp ut; ut.ut_user[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:9368: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9545: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_USER=yes else @@ -9385,13 +9562,13 @@ EOF fi echo $ac_n "checking for ut_id in utmp""... $ac_c" 1>&6 -echo "configure:9389: checking for ut_id in utmp" >&5 +echo "configure:9566: checking for ut_id in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_ID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9395 "configure" +#line 9572 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9399,7 +9576,7 @@ int main() { struct utmp ut; ut.ut_id[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:9403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9580: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_ID=yes else @@ -9420,13 +9597,13 @@ EOF fi echo $ac_n "checking for ut_host in utmp""... $ac_c" 1>&6 -echo "configure:9424: checking for ut_host in utmp" >&5 +echo "configure:9601: checking for ut_host in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_HOST'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9430 "configure" +#line 9607 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9434,7 +9611,7 @@ int main() { struct utmp ut; ut.ut_host[0] = 'a'; ; return 0; } EOF -if { (eval echo configure:9438: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_HOST=yes else @@ -9455,13 +9632,13 @@ EOF fi echo $ac_n "checking for ut_time in utmp""... $ac_c" 1>&6 -echo "configure:9459: checking for ut_time in utmp" >&5 +echo "configure:9636: checking for ut_time in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_TIME'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9465 "configure" +#line 9642 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9469,7 +9646,7 @@ int main() { struct utmp ut; time_t t; ut.ut_time = t; ; return 0; } EOF -if { (eval echo configure:9473: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9650: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_TIME=yes else @@ -9490,13 +9667,13 @@ EOF fi echo $ac_n "checking for ut_tv in utmp""... $ac_c" 1>&6 -echo "configure:9494: checking for ut_tv in utmp" >&5 +echo "configure:9671: checking for ut_tv in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_TV'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9500 "configure" +#line 9677 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9504,7 +9681,7 @@ int main() { struct utmp ut; struct timeval tv; ut.ut_tv = tv; ; return 0; } EOF -if { (eval echo configure:9508: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9685: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_TV=yes else @@ -9525,13 +9702,13 @@ EOF fi echo $ac_n "checking for ut_type in utmp""... $ac_c" 1>&6 -echo "configure:9529: checking for ut_type in utmp" >&5 +echo "configure:9706: checking for ut_type in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_TYPE'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9535 "configure" +#line 9712 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9539,7 +9716,7 @@ int main() { struct utmp ut; ut.ut_type = 0; ; return 0; } EOF -if { (eval echo configure:9543: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9720: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_TYPE=yes else @@ -9560,13 +9737,13 @@ EOF fi echo $ac_n "checking for ut_pid in utmp""... $ac_c" 1>&6 -echo "configure:9564: checking for ut_pid in utmp" >&5 +echo "configure:9741: checking for ut_pid in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_PID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9570 "configure" +#line 9747 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9574,7 +9751,7 @@ int main() { struct utmp ut; ut.ut_pid = 0; ; return 0; } EOF -if { (eval echo configure:9578: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9755: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_PID=yes else @@ -9595,13 +9772,13 @@ EOF fi echo $ac_n "checking for ut_exit in utmp""... $ac_c" 1>&6 -echo "configure:9599: checking for ut_exit in utmp" >&5 +echo "configure:9776: checking for ut_exit in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_EXIT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9605 "configure" +#line 9782 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9609,7 +9786,7 @@ int main() { struct utmp ut; ut.ut_exit.e_exit = 0; ; return 0; } EOF -if { (eval echo configure:9613: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_EXIT=yes else @@ -9630,13 +9807,13 @@ EOF fi echo $ac_n "checking for ut_addr in utmp""... $ac_c" 1>&6 -echo "configure:9634: checking for ut_addr in utmp" >&5 +echo "configure:9811: checking for ut_addr in utmp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UT_UT_ADDR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9640 "configure" +#line 9817 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9644,7 +9821,7 @@ int main() { struct utmp ut; ut.ut_addr = 0; ; return 0; } EOF -if { (eval echo configure:9648: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9825: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UT_UT_ADDR=yes else @@ -9666,13 +9843,13 @@ fi if test x$ac_cv_func_pututline = xyes ; then echo $ac_n "checking whether pututline returns pointer""... $ac_c" 1>&6 -echo "configure:9670: checking whether pututline returns pointer" >&5 +echo "configure:9847: checking whether pututline returns pointer" >&5 if eval "test \"`echo '$''{'samba_cv_PUTUTLINE_RETURNS_UTMP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9676 "configure" +#line 9853 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmp.h> @@ -9680,7 +9857,7 @@ int main() { struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg); ; return 0; } EOF -if { (eval echo configure:9684: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9861: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_PUTUTLINE_RETURNS_UTMP=yes else @@ -9702,13 +9879,13 @@ EOF fi echo $ac_n "checking for ut_syslen in utmpx""... $ac_c" 1>&6 -echo "configure:9706: checking for ut_syslen in utmpx" >&5 +echo "configure:9883: checking for ut_syslen in utmpx" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UX_UT_SYSLEN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9712 "configure" +#line 9889 "configure" #include "confdefs.h" #include <sys/types.h> #include <utmpx.h> @@ -9716,7 +9893,7 @@ int main() { struct utmpx ux; ux.ut_syslen = 0; ; return 0; } EOF -if { (eval echo configure:9720: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9897: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UX_UT_SYSLEN=yes else @@ -9737,7 +9914,7 @@ EOF fi echo $ac_n "checking for Linux kernel oplocks""... $ac_c" 1>&6 -echo "configure:9741: checking for Linux kernel oplocks" >&5 +echo "configure:9918: checking for Linux kernel oplocks" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_OPLOCKS_LINUX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9746,7 +9923,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=cross else cat > conftest.$ac_ext <<EOF -#line 9750 "configure" +#line 9927 "configure" #include "confdefs.h" #include <sys/types.h> @@ -9760,7 +9937,7 @@ main() { } EOF -if { (eval echo configure:9764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=yes else @@ -9783,7 +9960,7 @@ EOF fi echo $ac_n "checking for kernel change notify support""... $ac_c" 1>&6 -echo "configure:9787: checking for kernel change notify support" >&5 +echo "configure:9964: checking for kernel change notify support" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_CHANGE_NOTIFY'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9792,7 +9969,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=cross else cat > conftest.$ac_ext <<EOF -#line 9796 "configure" +#line 9973 "configure" #include "confdefs.h" #include <sys/types.h> @@ -9806,7 +9983,7 @@ main() { } EOF -if { (eval echo configure:9810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=yes else @@ -9829,7 +10006,7 @@ EOF fi echo $ac_n "checking for kernel share modes""... $ac_c" 1>&6 -echo "configure:9833: checking for kernel share modes" >&5 +echo "configure:10010: checking for kernel share modes" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_SHARE_MODES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9838,7 +10015,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_KERNEL_SHARE_MODES=cross else cat > conftest.$ac_ext <<EOF -#line 9842 "configure" +#line 10019 "configure" #include "confdefs.h" #include <sys/types.h> @@ -9854,7 +10031,7 @@ main() { } EOF -if { (eval echo configure:9858: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10035: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_KERNEL_SHARE_MODES=yes else @@ -9880,13 +10057,13 @@ fi echo $ac_n "checking for IRIX kernel oplock type definitions""... $ac_c" 1>&6 -echo "configure:9884: checking for IRIX kernel oplock type definitions" >&5 +echo "configure:10061: checking for IRIX kernel oplock type definitions" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_OPLOCKS_IRIX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9890 "configure" +#line 10067 "configure" #include "confdefs.h" #include <sys/types.h> #include <fcntl.h> @@ -9894,7 +10071,7 @@ int main() { oplock_stat_t t; t.os_state = OP_REVOKE; t.os_dev = 1; t.os_ino = 1; ; return 0; } EOF -if { (eval echo configure:9898: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10075: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_KERNEL_OPLOCKS_IRIX=yes else @@ -9915,7 +10092,7 @@ EOF fi echo $ac_n "checking for irix specific capabilities""... $ac_c" 1>&6 -echo "configure:9919: checking for irix specific capabilities" >&5 +echo "configure:10096: checking for irix specific capabilities" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9924,7 +10101,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=cross else cat > conftest.$ac_ext <<EOF -#line 9928 "configure" +#line 10105 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/capability.h> @@ -9939,7 +10116,7 @@ main() { } EOF -if { (eval echo configure:9943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10120: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=yes else @@ -9967,13 +10144,13 @@ fi # echo $ac_n "checking for int16 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:9971: checking for int16 typedef included by rpc/rpc.h" >&5 +echo "configure:10148: checking for int16 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_INT16_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 9977 "configure" +#line 10154 "configure" #include "confdefs.h" #include <sys/types.h> #if defined(HAVE_RPC_RPC_H) @@ -9983,7 +10160,7 @@ int main() { int16 testvar; ; return 0; } EOF -if { (eval echo configure:9987: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10164: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_INT16_FROM_RPC_RPC_H=yes else @@ -10004,13 +10181,13 @@ EOF fi echo $ac_n "checking for uint16 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10008: checking for uint16 typedef included by rpc/rpc.h" >&5 +echo "configure:10185: checking for uint16 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UINT16_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 10014 "configure" +#line 10191 "configure" #include "confdefs.h" #include <sys/types.h> #if defined(HAVE_RPC_RPC_H) @@ -10020,7 +10197,7 @@ int main() { uint16 testvar; ; return 0; } EOF -if { (eval echo configure:10024: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10201: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UINT16_FROM_RPC_RPC_H=yes else @@ -10041,13 +10218,13 @@ EOF fi echo $ac_n "checking for int32 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10045: checking for int32 typedef included by rpc/rpc.h" >&5 +echo "configure:10222: checking for int32 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_INT32_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 10051 "configure" +#line 10228 "configure" #include "confdefs.h" #include <sys/types.h> #if defined(HAVE_RPC_RPC_H) @@ -10057,7 +10234,7 @@ int main() { int32 testvar; ; return 0; } EOF -if { (eval echo configure:10061: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10238: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_INT32_FROM_RPC_RPC_H=yes else @@ -10078,13 +10255,13 @@ EOF fi echo $ac_n "checking for uint32 typedef included by rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10082: checking for uint32 typedef included by rpc/rpc.h" >&5 +echo "configure:10259: checking for uint32 typedef included by rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_UINT32_FROM_RPC_RPC_H'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 10088 "configure" +#line 10265 "configure" #include "confdefs.h" #include <sys/types.h> #if defined(HAVE_RPC_RPC_H) @@ -10094,7 +10271,7 @@ int main() { uint32 testvar; ; return 0; } EOF -if { (eval echo configure:10098: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10275: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_UINT32_FROM_RPC_RPC_H=yes else @@ -10116,13 +10293,13 @@ fi echo $ac_n "checking for conflicting AUTH_ERROR define in rpc/rpc.h""... $ac_c" 1>&6 -echo "configure:10120: checking for conflicting AUTH_ERROR define in rpc/rpc.h" >&5 +echo "configure:10297: checking for conflicting AUTH_ERROR define in rpc/rpc.h" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 10126 "configure" +#line 10303 "configure" #include "confdefs.h" #include <sys/types.h> #ifdef HAVE_SYS_SECURITY_H @@ -10136,7 +10313,7 @@ int main() { int testvar; ; return 0; } EOF -if { (eval echo configure:10140: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no else @@ -10157,16 +10334,16 @@ EOF fi echo $ac_n "checking for test routines""... $ac_c" 1>&6 -echo "configure:10161: checking for test routines" >&5 +echo "configure:10338: checking for test routines" >&5 if test "$cross_compiling" = yes; then echo "configure: warning: cannot run when cross-compiling" 1>&2 else cat > conftest.$ac_ext <<EOF -#line 10166 "configure" +#line 10343 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/trivial.c" EOF -if { (eval echo configure:10170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10347: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 else @@ -10180,7 +10357,7 @@ fi echo $ac_n "checking for ftruncate extend""... $ac_c" 1>&6 -echo "configure:10184: checking for ftruncate extend" >&5 +echo "configure:10361: checking for ftruncate extend" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FTRUNCATE_EXTEND'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10189,11 +10366,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_FTRUNCATE_EXTEND=cross else cat > conftest.$ac_ext <<EOF -#line 10193 "configure" +#line 10370 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/ftruncate.c" EOF -if { (eval echo configure:10197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_FTRUNCATE_EXTEND=yes else @@ -10216,7 +10393,7 @@ EOF fi echo $ac_n "checking for broken getgroups""... $ac_c" 1>&6 -echo "configure:10220: checking for broken getgroups" >&5 +echo "configure:10397: checking for broken getgroups" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_GETGROUPS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10225,11 +10402,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_BROKEN_GETGROUPS=cross else cat > conftest.$ac_ext <<EOF -#line 10229 "configure" +#line 10406 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/getgroups.c" EOF -if { (eval echo configure:10233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10410: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_BROKEN_GETGROUPS=yes else @@ -10252,15 +10429,15 @@ EOF fi echo $ac_n "checking whether getpass should be replaced""... $ac_c" 1>&6 -echo "configure:10256: checking whether getpass should be replaced" >&5 +echo "configure:10433: checking whether getpass should be replaced" >&5 if eval "test \"`echo '$''{'samba_cv_REPLACE_GETPASS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper" +CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper" cat > conftest.$ac_ext <<EOF -#line 10264 "configure" +#line 10441 "configure" #include "confdefs.h" #define REPLACE_GETPASS 1 @@ -10273,7 +10450,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:10277: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10454: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_REPLACE_GETPASS=yes else @@ -10296,7 +10473,7 @@ EOF fi echo $ac_n "checking for broken inet_ntoa""... $ac_c" 1>&6 -echo "configure:10300: checking for broken inet_ntoa" >&5 +echo "configure:10477: checking for broken inet_ntoa" >&5 if eval "test \"`echo '$''{'samba_cv_REPLACE_INET_NTOA'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10305,7 +10482,7 @@ if test "$cross_compiling" = yes; then samba_cv_REPLACE_INET_NTOA=cross else cat > conftest.$ac_ext <<EOF -#line 10309 "configure" +#line 10486 "configure" #include "confdefs.h" #include <stdio.h> @@ -10319,7 +10496,7 @@ if (strcmp(inet_ntoa(ip),"18.52.86.120") && strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } exit(1);} EOF -if { (eval echo configure:10323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_REPLACE_INET_NTOA=yes else @@ -10342,7 +10519,7 @@ EOF fi echo $ac_n "checking for secure mkstemp""... $ac_c" 1>&6 -echo "configure:10346: checking for secure mkstemp" >&5 +echo "configure:10523: checking for secure mkstemp" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_SECURE_MKSTEMP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10351,7 +10528,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_SECURE_MKSTEMP=cross else cat > conftest.$ac_ext <<EOF -#line 10355 "configure" +#line 10532 "configure" #include "confdefs.h" #include <stdlib.h> #include <sys/types.h> @@ -10368,7 +10545,7 @@ main() { exit(0); } EOF -if { (eval echo configure:10372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_SECURE_MKSTEMP=yes else @@ -10391,7 +10568,7 @@ EOF fi echo $ac_n "checking for sysconf(_SC_NGROUPS_MAX)""... $ac_c" 1>&6 -echo "configure:10395: checking for sysconf(_SC_NGROUPS_MAX)" >&5 +echo "configure:10572: checking for sysconf(_SC_NGROUPS_MAX)" >&5 if eval "test \"`echo '$''{'samba_cv_SYSCONF_SC_NGROUPS_MAX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10400,12 +10577,12 @@ if test "$cross_compiling" = yes; then samba_cv_SYSCONF_SC_NGROUPS_MAX=cross else cat > conftest.$ac_ext <<EOF -#line 10404 "configure" +#line 10581 "configure" #include "confdefs.h" #include <unistd.h> main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); } EOF -if { (eval echo configure:10409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_SYSCONF_SC_NGROUPS_MAX=yes else @@ -10428,7 +10605,7 @@ EOF fi echo $ac_n "checking for root""... $ac_c" 1>&6 -echo "configure:10432: checking for root" >&5 +echo "configure:10609: checking for root" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10437,11 +10614,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_ROOT=cross else cat > conftest.$ac_ext <<EOF -#line 10441 "configure" +#line 10618 "configure" #include "confdefs.h" main() { exit(getuid() != 0); } EOF -if { (eval echo configure:10445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10622: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_ROOT=yes else @@ -10469,7 +10646,7 @@ fi # look for a method of finding the list of network interfaces iface=no; echo $ac_n "checking for iface AIX""... $ac_c" 1>&6 -echo "configure:10473: checking for iface AIX" >&5 +echo "configure:10650: checking for iface AIX" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_AIX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10478,7 +10655,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_AIX=cross else cat > conftest.$ac_ext <<EOF -#line 10482 "configure" +#line 10659 "configure" #include "confdefs.h" #define HAVE_IFACE_AIX 1 @@ -10486,7 +10663,7 @@ else #include "confdefs.h" #include "${srcdir-.}/lib/interfaces.c" EOF -if { (eval echo configure:10490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_AIX=yes else @@ -10510,7 +10687,7 @@ fi if test $iface = no; then echo $ac_n "checking for iface ifconf""... $ac_c" 1>&6 -echo "configure:10514: checking for iface ifconf" >&5 +echo "configure:10691: checking for iface ifconf" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFCONF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10519,7 +10696,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_IFCONF=cross else cat > conftest.$ac_ext <<EOF -#line 10523 "configure" +#line 10700 "configure" #include "confdefs.h" #define HAVE_IFACE_IFCONF 1 @@ -10527,7 +10704,7 @@ else #include "confdefs.h" #include "${srcdir-.}/lib/interfaces.c" EOF -if { (eval echo configure:10531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_IFCONF=yes else @@ -10552,7 +10729,7 @@ fi if test $iface = no; then echo $ac_n "checking for iface ifreq""... $ac_c" 1>&6 -echo "configure:10556: checking for iface ifreq" >&5 +echo "configure:10733: checking for iface ifreq" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFREQ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10561,7 +10738,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_IFREQ=cross else cat > conftest.$ac_ext <<EOF -#line 10565 "configure" +#line 10742 "configure" #include "confdefs.h" #define HAVE_IFACE_IFREQ 1 @@ -10569,7 +10746,7 @@ else #include "confdefs.h" #include "${srcdir-.}/lib/interfaces.c" EOF -if { (eval echo configure:10573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_IFREQ=yes else @@ -10598,7 +10775,7 @@ fi seteuid=no; if test $seteuid = no; then echo $ac_n "checking for setresuid""... $ac_c" 1>&6 -echo "configure:10602: checking for setresuid" >&5 +echo "configure:10779: checking for setresuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETRESUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10607,7 +10784,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETRESUID=cross else cat > conftest.$ac_ext <<EOF -#line 10611 "configure" +#line 10788 "configure" #include "confdefs.h" #define AUTOCONF_TEST 1 @@ -10615,7 +10792,7 @@ else #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c" EOF -if { (eval echo configure:10619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETRESUID=yes else @@ -10641,7 +10818,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for setreuid""... $ac_c" 1>&6 -echo "configure:10645: checking for setreuid" >&5 +echo "configure:10822: checking for setreuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETREUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10650,7 +10827,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETREUID=cross else cat > conftest.$ac_ext <<EOF -#line 10654 "configure" +#line 10831 "configure" #include "confdefs.h" #define AUTOCONF_TEST 1 @@ -10658,7 +10835,7 @@ else #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c" EOF -if { (eval echo configure:10662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10839: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETREUID=yes else @@ -10683,7 +10860,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for seteuid""... $ac_c" 1>&6 -echo "configure:10687: checking for seteuid" >&5 +echo "configure:10864: checking for seteuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETEUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10692,7 +10869,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETEUID=cross else cat > conftest.$ac_ext <<EOF -#line 10696 "configure" +#line 10873 "configure" #include "confdefs.h" #define AUTOCONF_TEST 1 @@ -10700,7 +10877,7 @@ else #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c" EOF -if { (eval echo configure:10704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETEUID=yes else @@ -10725,7 +10902,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for setuidx""... $ac_c" 1>&6 -echo "configure:10729: checking for setuidx" >&5 +echo "configure:10906: checking for setuidx" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETUIDX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10734,7 +10911,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETUIDX=cross else cat > conftest.$ac_ext <<EOF -#line 10738 "configure" +#line 10915 "configure" #include "confdefs.h" #define AUTOCONF_TEST 1 @@ -10742,7 +10919,7 @@ else #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c" EOF -if { (eval echo configure:10746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETUIDX=yes else @@ -10767,7 +10944,7 @@ fi echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:10771: checking for working mmap" >&5 +echo "configure:10948: checking for working mmap" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_MMAP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10776,11 +10953,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_MMAP=cross else cat > conftest.$ac_ext <<EOF -#line 10780 "configure" +#line 10957 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/shared_mmap.c" EOF -if { (eval echo configure:10784: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_MMAP=yes else @@ -10803,7 +10980,7 @@ EOF fi echo $ac_n "checking for ftruncate needs root""... $ac_c" 1>&6 -echo "configure:10807: checking for ftruncate needs root" >&5 +echo "configure:10984: checking for ftruncate needs root" >&5 if eval "test \"`echo '$''{'samba_cv_FTRUNCATE_NEEDS_ROOT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10812,11 +10989,11 @@ if test "$cross_compiling" = yes; then samba_cv_FTRUNCATE_NEEDS_ROOT=cross else cat > conftest.$ac_ext <<EOF -#line 10816 "configure" +#line 10993 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/ftruncroot.c" EOF -if { (eval echo configure:10820: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_FTRUNCATE_NEEDS_ROOT=yes else @@ -10839,7 +11016,7 @@ EOF fi echo $ac_n "checking for fcntl locking""... $ac_c" 1>&6 -echo "configure:10843: checking for fcntl locking" >&5 +echo "configure:11020: checking for fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FCNTL_LOCK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10848,11 +11025,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_FCNTL_LOCK=cross else cat > conftest.$ac_ext <<EOF -#line 10852 "configure" +#line 11029 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/fcntl_lock.c" EOF -if { (eval echo configure:10856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_FCNTL_LOCK=yes else @@ -10875,7 +11052,7 @@ EOF fi echo $ac_n "checking for broken (glibc2.1/x86) 64 bit fcntl locking""... $ac_c" 1>&6 -echo "configure:10879: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5 +echo "configure:11056: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_FCNTL64_LOCKS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10884,11 +11061,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross else cat > conftest.$ac_ext <<EOF -#line 10888 "configure" +#line 11065 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/fcntl_lock64.c" EOF -if { (eval echo configure:10892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes else @@ -10913,7 +11090,7 @@ else echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6 -echo "configure:10917: checking for 64 bit fcntl locking" >&5 +echo "configure:11094: checking for 64 bit fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_FLOCK64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10922,7 +11099,7 @@ else samba_cv_HAVE_STRUCT_FLOCK64=cross else cat > conftest.$ac_ext <<EOF -#line 10926 "configure" +#line 11103 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -10946,7 +11123,7 @@ exit(1); #endif } EOF -if { (eval echo configure:10950: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_STRUCT_FLOCK64=yes else @@ -10971,7 +11148,7 @@ EOF fi echo $ac_n "checking for a crypt that needs truncated salt""... $ac_c" 1>&6 -echo "configure:10975: checking for a crypt that needs truncated salt" >&5 +echo "configure:11152: checking for a crypt that needs truncated salt" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_TRUNCATED_SALT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10980,11 +11157,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_TRUNCATED_SALT=cross else cat > conftest.$ac_ext <<EOF -#line 10984 "configure" +#line 11161 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/crypttest.c" EOF -if { (eval echo configure:10988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_TRUNCATED_SALT=no else @@ -11007,13 +11184,13 @@ EOF fi echo $ac_n "checking for broken nisplus include files""... $ac_c" 1>&6 -echo "configure:11011: checking for broken nisplus include files" >&5 +echo "configure:11188: checking for broken nisplus include files" >&5 if eval "test \"`echo '$''{'samba_cv_BROKEN_NISPLUS_INCLUDE_FILES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 11017 "configure" +#line 11194 "configure" #include "confdefs.h" #include <sys/acl.h> #if defined(HAVE_RPCSVC_NIS_H) @@ -11023,7 +11200,7 @@ int main() { return 0; ; return 0; } EOF -if { (eval echo configure:11027: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11204: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no else @@ -11047,7 +11224,7 @@ fi ################################################# # check for smbwrapper support echo $ac_n "checking whether to use smbwrapper""... $ac_c" 1>&6 -echo "configure:11051: checking whether to use smbwrapper" >&5 +echo "configure:11228: checking whether to use smbwrapper" >&5 # Check whether --with-smbwrapper or --without-smbwrapper was given. if test "${with_smbwrapper+set}" = set; then withval="$with_smbwrapper" @@ -11091,7 +11268,7 @@ fi ################################################# # check for the AFS filesystem echo $ac_n "checking whether to use AFS""... $ac_c" 1>&6 -echo "configure:11095: checking whether to use AFS" >&5 +echo "configure:11272: checking whether to use AFS" >&5 # Check whether --with-afs or --without-afs was given. if test "${with_afs+set}" = set; then withval="$with_afs" @@ -11117,7 +11294,7 @@ fi ################################################# # check for the DFS auth system echo $ac_n "checking whether to use DFS auth""... $ac_c" 1>&6 -echo "configure:11121: checking whether to use DFS auth" >&5 +echo "configure:11298: checking whether to use DFS auth" >&5 # Check whether --with-dfs or --without-dfs was given. if test "${with_dfs+set}" = set; then withval="$with_dfs" @@ -11142,7 +11319,7 @@ fi ################################################# # check for Kerberos IV auth system echo $ac_n "checking whether to use Kerberos IV""... $ac_c" 1>&6 -echo "configure:11146: checking whether to use Kerberos IV" >&5 +echo "configure:11323: checking whether to use Kerberos IV" >&5 # Check whether --with-krb4 or --without-krb4 was given. if test "${with_krb4+set}" = set; then withval="$with_krb4" @@ -11152,7 +11329,7 @@ if test "${with_krb4+set}" = set; then EOF echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 -echo "configure:11156: checking for dn_expand in -lresolv" >&5 +echo "configure:11333: checking for dn_expand in -lresolv" >&5 ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11160,7 +11337,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <<EOF -#line 11164 "configure" +#line 11341 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -11171,7 +11348,7 @@ int main() { dn_expand() ; return 0; } EOF -if { (eval echo configure:11175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -11210,7 +11387,7 @@ fi ################################################# # check for Kerberos 5 auth system echo $ac_n "checking whether to use Kerberos 5""... $ac_c" 1>&6 -echo "configure:11214: checking whether to use Kerberos 5" >&5 +echo "configure:11391: checking whether to use Kerberos 5" >&5 # Check whether --with-krb5 or --without-krb5 was given. if test "${with_krb5+set}" = set; then withval="$with_krb5" @@ -11231,7 +11408,7 @@ fi ################################################# # check for automount support echo $ac_n "checking whether to use AUTOMOUNT""... $ac_c" 1>&6 -echo "configure:11235: checking whether to use AUTOMOUNT" >&5 +echo "configure:11412: checking whether to use AUTOMOUNT" >&5 # Check whether --with-automount or --without-automount was given. if test "${with_automount+set}" = set; then withval="$with_automount" @@ -11256,7 +11433,7 @@ fi ################################################# # check for smbmount support echo $ac_n "checking whether to use SMBMOUNT""... $ac_c" 1>&6 -echo "configure:11260: checking whether to use SMBMOUNT" >&5 +echo "configure:11437: checking whether to use SMBMOUNT" >&5 # Check whether --with-smbmount or --without-smbmount was given. if test "${with_smbmount+set}" = set; then withval="$with_smbmount" @@ -11284,8 +11461,9 @@ fi ################################################# # check for a PAM password database +with_pam_for_crypt=no echo $ac_n "checking whether to use PAM password database""... $ac_c" 1>&6 -echo "configure:11289: checking whether to use PAM password database" >&5 +echo "configure:11467: checking whether to use PAM password database" >&5 # Check whether --with-pam or --without-pam was given. if test "${with_pam+set}" = set; then withval="$with_pam" @@ -11297,6 +11475,89 @@ if test "${with_pam+set}" = set; then EOF LIBS="$LIBS -lpam" + with_pam_for_crypt=yes + ;; + *) + echo "$ac_t""no" 1>&6 + ;; + esac +else + echo "$ac_t""no" 1>&6 + +fi + + +# we can't build a pam module if we don't have pam. +echo $ac_n "checking for pam_get_data in -lpam""... $ac_c" 1>&6 +echo "configure:11493: checking for pam_get_data in -lpam" >&5 +ac_lib_var=`echo pam'_'pam_get_data | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpam $LIBS" +cat > conftest.$ac_ext <<EOF +#line 11501 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pam_get_data(); + +int main() { +pam_get_data() +; return 0; } +EOF +if { (eval echo configure:11512: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBPAM 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +################################################# +# check for pam_smbpass support +echo $ac_n "checking whether to use pam_smbpass""... $ac_c" 1>&6 +echo "configure:11539: checking whether to use pam_smbpass" >&5 +# Check whether --with-pam_smbpass or --without-pam_smbpass was given. +if test "${with_pam_smbpass+set}" = set; then + withval="$with_pam_smbpass" + case "$withval" in + yes) + echo "$ac_t""yes" 1>&6 + +# Conditions under which pam_smbpass should not be built. + + if test x$PICFLAG = x; then + echo "$ac_t""No support for PIC code - disabling pam_smbpass" 1>&6 + PAM_MOD="" + elif test x$ac_cv_lib_pam_pam_get_data = xno; then + echo "$ac_t""No libpam found -- disabling pam_smbpass" 1>&6 + PAM_MOD="" + else + cat >> confdefs.h <<\EOF +#define WITH_PAM_SMBPASS 1 +EOF + + PAM_MOD="bin/pam_smbpass.so" + fi ;; *) echo "$ac_t""no" 1>&6 @@ -11308,6 +11569,115 @@ else fi + +############################################### +# test for where we get crypt() from, but only +# if not using PAM +if test $with_pam_for_crypt = no; then +for ac_func in crypt +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:11581: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 11586 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:11609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +if test x"$ac_cv_func_crypt" = x"no"; then + echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 +echo "configure:11635: checking for crypt in -lcrypt" >&5 +ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrypt $LIBS" +cat > conftest.$ac_ext <<EOF +#line 11643 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char crypt(); + +int main() { +crypt() +; return 0; } +EOF +if { (eval echo configure:11654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lcrypt"; + cat >> confdefs.h <<\EOF +#define HAVE_CRYPT 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +fi +fi + + ################################################# # removed until we get the code actually working # --jeremy @@ -11354,7 +11724,7 @@ fi ################################################# # check for a NISPLUS password database echo $ac_n "checking whether to use NISPLUS password database""... $ac_c" 1>&6 -echo "configure:11358: checking whether to use NISPLUS password database" >&5 +echo "configure:11728: checking whether to use NISPLUS password database" >&5 # Check whether --with-nisplus or --without-nisplus was given. if test "${with_nisplus+set}" = set; then withval="$with_nisplus" @@ -11379,7 +11749,7 @@ fi ################################################# # check for a NISPLUS_HOME support echo $ac_n "checking whether to use NISPLUS_HOME""... $ac_c" 1>&6 -echo "configure:11383: checking whether to use NISPLUS_HOME" >&5 +echo "configure:11753: checking whether to use NISPLUS_HOME" >&5 # Check whether --with-nisplus-home or --without-nisplus-home was given. if test "${with_nisplus_home+set}" = set; then withval="$with_nisplus_home" @@ -11404,7 +11774,7 @@ fi ################################################# # check for the secure socket layer echo $ac_n "checking whether to use SSL""... $ac_c" 1>&6 -echo "configure:11408: checking whether to use SSL" >&5 +echo "configure:11778: checking whether to use SSL" >&5 # Check whether --with-ssl or --without-ssl was given. if test "${with_ssl+set}" = set; then withval="$with_ssl" @@ -11428,7 +11798,7 @@ EOF LDFLAGS="=L/usr/local/ssl/lib $LDFLAGS" ;; * ) - CFLAGS="-I${withval}/include $CFLAGS" + CFLAGS="-I${withval} $CFLAGS" LIBS="-lssl -lcrypto $LIBS" LDFLAGS="-L${withval}/lib $LDFLAGS" ;; @@ -11463,7 +11833,7 @@ fi ################################################# # check for syslog logging echo $ac_n "checking whether to use syslog logging""... $ac_c" 1>&6 -echo "configure:11467: checking whether to use syslog logging" >&5 +echo "configure:11837: checking whether to use syslog logging" >&5 # Check whether --with-syslog or --without-syslog was given. if test "${with_syslog+set}" = set; then withval="$with_syslog" @@ -11488,7 +11858,7 @@ fi ################################################# # check for a shared memory profiling support echo $ac_n "checking whether to use profiling""... $ac_c" 1>&6 -echo "configure:11492: checking whether to use profiling" >&5 +echo "configure:11862: checking whether to use profiling" >&5 # Check whether --with-profile or --without-profile was given. if test "${with_profile+set}" = set; then withval="$with_profile" @@ -11514,7 +11884,7 @@ fi ################################################# # check for experimental netatalk resource fork support echo $ac_n "checking whether to support netatalk""... $ac_c" 1>&6 -echo "configure:11518: checking whether to support netatalk" >&5 +echo "configure:11888: checking whether to support netatalk" >&5 # Check whether --with-netatalk or --without-netatalk was given. if test "${with_netatalk+set}" = set; then withval="$with_netatalk" @@ -11541,7 +11911,7 @@ fi QUOTAOBJS=smbd/noquotas.o echo $ac_n "checking whether to support disk-quotas""... $ac_c" 1>&6 -echo "configure:11545: checking whether to support disk-quotas" >&5 +echo "configure:11915: checking whether to support disk-quotas" >&5 # Check whether --with-quotas or --without-quotas was given. if test "${with_quotas+set}" = set; then withval="$with_quotas" @@ -11565,7 +11935,7 @@ fi # check for experimental utmp accounting echo $ac_n "checking whether to support utmp accounting""... $ac_c" 1>&6 -echo "configure:11569: checking whether to support utmp accounting" >&5 +echo "configure:11939: checking whether to support utmp accounting" >&5 # Check whether --with-utmp or --without-utmp was given. if test "${with_utmp+set}" = set; then withval="$with_utmp" @@ -11591,7 +11961,7 @@ fi # check for MS Dfs support echo $ac_n "checking whether to support Microsoft Dfs""... $ac_c" 1>&6 -echo "configure:11595: checking whether to support Microsoft Dfs" >&5 +echo "configure:11965: checking whether to support Microsoft Dfs" >&5 # Check whether --with-msdfs or --without-msdfs was given. if test "${with_msdfs+set}" = set; then withval="$with_msdfs" @@ -11617,7 +11987,7 @@ fi # check for Samba VFS support echo $ac_n "checking whether to support the experimantal Samba vfs""... $ac_c" 1>&6 -echo "configure:11621: checking whether to support the experimantal Samba vfs" >&5 +echo "configure:11991: checking whether to support the experimantal Samba vfs" >&5 # Check whether --with-vfs or --without-vfs was given. if test "${with_vfs+set}" = set; then withval="$with_vfs" @@ -11642,14 +12012,14 @@ fi ################################################# # these tests are taken from the GNU fileutils package echo "checking how to get filesystem space usage" 1>&6 -echo "configure:11646: checking how to get filesystem space usage" >&5 +echo "configure:12016: checking how to get filesystem space usage" >&5 space=no # Test for statvfs64. if test $space = no; then # SVR4 echo $ac_n "checking statvfs64 function (SVR4)""... $ac_c" 1>&6 -echo "configure:11653: checking statvfs64 function (SVR4)" >&5 +echo "configure:12023: checking statvfs64 function (SVR4)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11657,7 +12027,7 @@ else fu_cv_sys_stat_statvfs64=cross else cat > conftest.$ac_ext <<EOF -#line 11661 "configure" +#line 12031 "configure" #include "confdefs.h" #if defined(HAVE_UNISTD_H) @@ -11671,7 +12041,7 @@ else exit (statvfs64 (".", &fsd)); } EOF -if { (eval echo configure:11675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statvfs64=yes else @@ -11704,12 +12074,12 @@ fi if test $space = no; then # SVR4 echo $ac_n "checking statvfs function (SVR4)""... $ac_c" 1>&6 -echo "configure:11708: checking statvfs function (SVR4)" >&5 +echo "configure:12078: checking statvfs function (SVR4)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 11713 "configure" +#line 12083 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/statvfs.h> @@ -11717,7 +12087,7 @@ int main() { struct statvfs fsd; statvfs (0, &fsd); ; return 0; } EOF -if { (eval echo configure:11721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* fu_cv_sys_stat_statvfs=yes else @@ -11742,7 +12112,7 @@ fi if test $space = no; then # DEC Alpha running OSF/1 echo $ac_n "checking for 3-argument statfs function (DEC OSF/1)""... $ac_c" 1>&6 -echo "configure:11746: checking for 3-argument statfs function (DEC OSF/1)" >&5 +echo "configure:12116: checking for 3-argument statfs function (DEC OSF/1)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs3_osf1'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11750,7 +12120,7 @@ else fu_cv_sys_stat_statfs3_osf1=no else cat > conftest.$ac_ext <<EOF -#line 11754 "configure" +#line 12124 "configure" #include "confdefs.h" #include <sys/param.h> @@ -11763,7 +12133,7 @@ else exit (statfs (".", &fsd, sizeof (struct statfs))); } EOF -if { (eval echo configure:11767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs3_osf1=yes else @@ -11790,7 +12160,7 @@ fi if test $space = no; then # AIX echo $ac_n "checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)""... $ac_c" 1>&6 -echo "configure:11794: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5 +echo "configure:12164: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_bsize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11798,7 +12168,7 @@ else fu_cv_sys_stat_statfs2_bsize=no else cat > conftest.$ac_ext <<EOF -#line 11802 "configure" +#line 12172 "configure" #include "confdefs.h" #ifdef HAVE_SYS_PARAM_H @@ -11817,7 +12187,7 @@ else exit (statfs (".", &fsd)); } EOF -if { (eval echo configure:11821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs2_bsize=yes else @@ -11844,7 +12214,7 @@ fi if test $space = no; then # SVR3 echo $ac_n "checking for four-argument statfs (AIX-3.2.5, SVR3)""... $ac_c" 1>&6 -echo "configure:11848: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5 +echo "configure:12218: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs4'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11852,7 +12222,7 @@ else fu_cv_sys_stat_statfs4=no else cat > conftest.$ac_ext <<EOF -#line 11856 "configure" +#line 12226 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/statfs.h> @@ -11862,7 +12232,7 @@ else exit (statfs (".", &fsd, sizeof fsd, 0)); } EOF -if { (eval echo configure:11866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs4=yes else @@ -11889,7 +12259,7 @@ fi if test $space = no; then # 4.4BSD and NetBSD echo $ac_n "checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)""... $ac_c" 1>&6 -echo "configure:11893: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5 +echo "configure:12263: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_fsize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11897,7 +12267,7 @@ else fu_cv_sys_stat_statfs2_fsize=no else cat > conftest.$ac_ext <<EOF -#line 11901 "configure" +#line 12271 "configure" #include "confdefs.h" #include <sys/types.h> #ifdef HAVE_SYS_PARAM_H @@ -11913,7 +12283,7 @@ else exit (statfs (".", &fsd)); } EOF -if { (eval echo configure:11917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs2_fsize=yes else @@ -11940,7 +12310,7 @@ fi if test $space = no; then # Ultrix echo $ac_n "checking for two-argument statfs with struct fs_data (Ultrix)""... $ac_c" 1>&6 -echo "configure:11944: checking for two-argument statfs with struct fs_data (Ultrix)" >&5 +echo "configure:12314: checking for two-argument statfs with struct fs_data (Ultrix)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_fs_data'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11948,7 +12318,7 @@ else fu_cv_sys_stat_fs_data=no else cat > conftest.$ac_ext <<EOF -#line 11952 "configure" +#line 12322 "configure" #include "confdefs.h" #include <sys/types.h> #ifdef HAVE_SYS_PARAM_H @@ -11968,7 +12338,7 @@ else exit (statfs (".", &fsd) != 1); } EOF -if { (eval echo configure:11972: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_fs_data=yes else @@ -12001,9 +12371,9 @@ fi # file support. # echo $ac_n "checking checking if large file support can be enabled""... $ac_c" 1>&6 -echo "configure:12005: checking checking if large file support can be enabled" >&5 +echo "configure:12375: checking checking if large file support can be enabled" >&5 cat > conftest.$ac_ext <<EOF -#line 12007 "configure" +#line 12377 "configure" #include "confdefs.h" #if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8))) @@ -12016,7 +12386,7 @@ int main() { int i ; return 0; } EOF -if { (eval echo configure:12020: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12390: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes else @@ -12083,7 +12453,7 @@ fi # check for ACL support echo $ac_n "checking whether to support ACLs""... $ac_c" 1>&6 -echo "configure:12087: checking whether to support ACLs" >&5 +echo "configure:12457: checking whether to support ACLs" >&5 # Check whether --with-acl-support or --without-acl-support was given. if test "${with_acl_support+set}" = set; then withval="$with_acl_support" @@ -12121,7 +12491,7 @@ EOF ;; *) echo $ac_n "checking for acl_get_file in -lacl""... $ac_c" 1>&6 -echo "configure:12125: checking for acl_get_file in -lacl" >&5 +echo "configure:12495: checking for acl_get_file in -lacl" >&5 ac_lib_var=`echo acl'_'acl_get_file | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12129,7 +12499,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lacl $LIBS" cat > conftest.$ac_ext <<EOF -#line 12133 "configure" +#line 12503 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -12140,7 +12510,7 @@ int main() { acl_get_file() ; return 0; } EOF -if { (eval echo configure:12144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -12168,13 +12538,13 @@ else fi echo $ac_n "checking for ACL support""... $ac_c" 1>&6 -echo "configure:12172: checking for ACL support" >&5 +echo "configure:12542: checking for ACL support" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_POSIX_ACLS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 12178 "configure" +#line 12548 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/acl.h> @@ -12182,7 +12552,7 @@ int main() { acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p); ; return 0; } EOF -if { (eval echo configure:12186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12556: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* samba_cv_HAVE_POSIX_ACLS=yes else @@ -12202,13 +12572,13 @@ echo "$ac_t""$samba_cv_HAVE_POSIX_ACLS" 1>&6 EOF echo $ac_n "checking for acl_get_perm_np""... $ac_c" 1>&6 -echo "configure:12206: checking for acl_get_perm_np" >&5 +echo "configure:12576: checking for acl_get_perm_np" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_ACL_GET_PERM_NP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 12212 "configure" +#line 12582 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/acl.h> @@ -12216,7 +12586,7 @@ int main() { acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm); ; return 0; } EOF -if { (eval echo configure:12220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12590: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* samba_cv_HAVE_ACL_GET_PERM_NP=yes else @@ -12236,41 +12606,6 @@ EOF fi fi - echo $ac_n "checking for XFS ACL support""... $ac_c" 1>&6 -echo "configure:12241: checking for XFS ACL support" >&5 -if eval "test \"`echo '$''{'samba_cv_HAVE_XFS_ACLS'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - - cat > conftest.$ac_ext <<EOF -#line 12247 "configure" -#include "confdefs.h" -#include <sys/types.h> -#include <acl/acl.h> -int main() { - char test_str[13] = SGI_ACL_FILE; -; return 0; } -EOF -if { (eval echo configure:12255: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - samba_cv_HAVE_XFS_ACLS=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - samba_cv_XFS_POSIX_ACLS=no -fi -rm -f conftest* -fi - -echo "$ac_t""$samba_cv_HAVE_XFS_ACLS" 1>&6 - if test x"$samba_cv_HAVE_XFS_ACLS" = x"yes"; then - echo "$ac_t""Using XFS ACLs" 1>&6 - cat >> confdefs.h <<\EOF -#define HAVE_XFS_ACLS 1 -EOF - - fi ;; esac ;; @@ -12305,11 +12640,11 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <<EOF -#line 12309 "configure" +#line 12644 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/summary.c" EOF -if { (eval echo configure:12313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "configure OK"; else @@ -12468,6 +12803,7 @@ s%@RUNPROG@%$RUNPROG%g s%@MPROGS@%$MPROGS%g s%@LDSHFLAGS@%$LDSHFLAGS%g s%@HOST_OS@%$HOST_OS%g +s%@PAM_MOD@%$PAM_MOD%g s%@WRAP@%$WRAP%g s%@WRAP32@%$WRAP32%g s%@PICFLAG@%$PICFLAG%g diff --git a/source/configure.in b/source/configure.in index a25300fe856..92f341e1299 100644 --- a/source/configure.in +++ b/source/configure.in @@ -25,7 +25,7 @@ AC_ARG_WITH(fhs, [ --with-fhs use FHS-compliant paths [default=no]], ################################################# # set private directory location AC_ARG_WITH(privatedir, -[ --with-privatedir=DIR Where to put smbpasswd ($privatedir)], +[ --with-privatedir=DIR Where to put smbpasswd ($ac_default_prefix/private)], [ case "$withval" in yes|no) # @@ -41,7 +41,7 @@ AC_ARG_WITH(privatedir, ################################################# # set lock directory location AC_ARG_WITH(lockdir, -[ --with-lockdir=DIR Where to put lock files ($lockdir)], +[ --with-lockdir=DIR Where to put lock files ($ac_default_prefix/var/locks)], [ case "$withval" in yes|no) # @@ -57,7 +57,7 @@ AC_ARG_WITH(lockdir, ################################################# # set SWAT directory location AC_ARG_WITH(swatdir, -[ --with-swatdir=DIR Where to put SWAT files ($swatdir)], +[ --with-swatdir=DIR Where to put SWAT files ($ac_default_prefix/swat)], [ case "$withval" in yes|no) # @@ -73,7 +73,7 @@ AC_ARG_WITH(swatdir, ################################################# # set configuration directory location AC_ARG_WITH(configdir, -[ --with-configdir=DIR Where to put configuration files ($configdir)], +[ --with-configdir=DIR Where to put configuration files (\$libdir)], [ case "$withval" in yes|no) # @@ -89,7 +89,7 @@ AC_ARG_WITH(configdir, ################################################# # set codepage directory location AC_ARG_WITH(codepagedir, -[ --with-codepagedir=DIR Where to put codepage files ($codepagedir)], +[ --with-codepagedir=DIR Where to put codepage files (\$libdir/codepages)], [ case "$withval" in yes|no) # @@ -118,6 +118,7 @@ AC_SUBST(RUNPROG) AC_SUBST(MPROGS) AC_SUBST(LDSHFLAGS) AC_SUBST(HOST_OS) +AC_SUBST(PAM_MOD) AC_SUBST(WRAP) AC_SUBST(WRAP32) AC_SUBST(PICFLAG) @@ -267,7 +268,7 @@ exit(1); *linux*) AC_MSG_CHECKING([for LFS support]) old_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS" + CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" AC_TRY_RUN([ #include <unistd.h> #include <sys/utsname.h> @@ -305,7 +306,7 @@ main() { ], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross]) CPPFLAGS="$old_CPPFLAGS" if test x$LINUX_LFS_SUPPORT = xyes ; then - CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS" + CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" fi AC_MSG_RESULT([$LINUX_LFS_SUPPORT]) ;; @@ -340,10 +341,12 @@ AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h) AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h) AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h) -AC_CHECK_HEADERS(sys/param.h ctype.h sys/un.h sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h) -AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h string.h strings.h stdlib.h sys/socket.h) +AC_CHECK_HEADERS(sys/param.h ctype.h sys/un.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/mode.h) +AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h) AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h) AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h) +AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h) + # # HPUX has a bug in that including shadow.h causes a re-definition of MAXINT. # This causes configure to fail to detect it. Check for shadow separately on HPUX. @@ -358,10 +361,10 @@ case "$host_os" in ;; esac AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) -AC_CHECK_HEADERS(nss.h sys/security.h security/pam_appl.h) +AC_CHECK_HEADERS(nss.h nss_common.h sys/security.h security/pam_appl.h security/pam_modules.h) AC_CHECK_HEADERS(stropts.h poll.h) AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h) -AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h acl/acl.h) +AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h) # For experimental utmp support (lastlog on some BSD-like systems) AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h) @@ -399,6 +402,19 @@ AC_CHECK_LIB(cups,httpConnect) AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl"; AC_DEFINE(HAVE_LIBDL)]) +AC_CACHE_CHECK([for socklen_t type],samba_cv_socklen_t, [ + AC_TRY_COMPILE([ +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +#include <sys/socket.h>],[socklen_t i = 0], + samba_cv_socklen_t=yes,samba_cv_socklen_t=no)]) +if test x"$samba_cv_socklen_t" = x"yes"; then + AC_DEFINE(HAVE_SOCKLEN_T_TYPE) +fi + AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [ AC_TRY_COMPILE([ #include <sys/types.h> @@ -412,28 +428,14 @@ if test x"$samba_cv_sig_atomic_t" = x"yes"; then AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE) fi -AC_CACHE_CHECK([for errno in errno.h],samba_cv_errno, [ - AC_TRY_COMPILE([#include <errno.h>],[int i = errno], - samba_cv_errno=yes,samba_cv_have_errno=no)]) -if test x"$samba_cv_errno" = x"yes"; then - AC_DEFINE(HAVE_ERRNO_DECL) -fi - -# stupid glibc has the functions but no declaration. grrrr. -AC_CACHE_CHECK([for setresuid declaration],samba_cv_have_setresuid_decl,[ - AC_TRY_COMPILE([#include <unistd.h>],[int i = (int)setresuid], - samba_cv_have_setresuid_decl=yes,samba_cv_have_setresuid_decl=no)]) -if test x"$samba_cv_have_setresuid_decl" = x"yes"; then - AC_DEFINE(HAVE_SETRESUID_DECL) -fi - -# stupid glibc has the functions but no declaration. grrrr. -AC_CACHE_CHECK([for setresgid declaration],samba_cv_have_setresgid_decl,[ - AC_TRY_COMPILE([#include <unistd.h>],[int i = (int)setresgid], - samba_cv_have_setresgid_decl=yes,samba_cv_have_setresgid_decl=no)]) -if test x"$samba_cv_have_setresgid_decl" = x"yes"; then - AC_DEFINE(HAVE_SETRESGID_DECL) -fi +# stupid headers have the functions but no declaration. grrrr. +AC_HAVE_DECL(errno, [#include <errno.h>]) +AC_HAVE_DECL(setresuid, [#include <unistd.h>]) +AC_HAVE_DECL(setresgid, [#include <unistd.h>]) +AC_HAVE_DECL(asprintf, [#include <stdio.h>]) +AC_HAVE_DECL(vasprintf, [#include <stdio.h>]) +AC_HAVE_DECL(vsnprintf, [#include <stdio.h>]) +AC_HAVE_DECL(snprintf, [#include <stdio.h>]) # and glibc has setresuid under linux but the function does # nothing until kernel 2.1.44! very dumb. @@ -459,14 +461,6 @@ fi AC_FUNC_MEMCMP ############################################### -# test for where we get crypt() from -AC_CHECK_FUNCS(crypt) -if test x"$ac_cv_func_crypt" = x"no"; then - AC_CHECK_LIB(crypt, crypt, [LIBS="$LIBS -lcrypt"; - AC_DEFINE(HAVE_CRYPT)]) -fi - -############################################### # Readline included by default unless explicitly asked not to test "${with_readline+set}" != "set" && with_readline=yes @@ -581,13 +575,13 @@ fi AC_CHECK_FUNCS(waitpid getcwd strdup strtoul strerror chown fchown chmod fchmod chroot) AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset) -AC_CHECK_FUNCS(memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid) +AC_CHECK_FUNCS(memmove vsnprintf snprintf asprintf vasprintf setsid glob strpbrk pipe crypt16 getauthuid) AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent) AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf) AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64) AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64) AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf) -AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl) +AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink) # syscall() is needed for smbwrapper. AC_CHECK_FUNCS(syscall) @@ -896,6 +890,30 @@ if test x"$samba_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then AC_DEFINE(HAVE_GETTIMEOFDAY_TZ) fi +AC_CACHE_CHECK([for C99 vsnprintf],samba_cv_HAVE_C99_VSNPRINTF,[ +AC_TRY_RUN([ +#include <sys/types.h> +#include <stdarg.h> +void foo(const char *format, ...) { + va_list ap; + int len; + char buf[5]; + + va_start(ap, format); + len = vsnprintf(0, 0, format, ap); + va_end(ap); + if (len != 5) exit(1); + + if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1); + + exit(0); +} +main() { foo("hello"); } +], +samba_cv_HAVE_C99_VSNPRINTF=yes,samba_cv_HAVE_C99_VSNPRINTF=no,samba_cv_HAVE_C99_VSNPRINTF=cross)]) +if test x"$samba_cv_HAVE_C99_VSNPRINTF" = x"yes"; then + AC_DEFINE(HAVE_C99_VSNPRINTF) +fi AC_CACHE_CHECK([for broken readdir],samba_cv_HAVE_BROKEN_READDIR,[ AC_TRY_RUN([#include <sys/types.h> @@ -1210,7 +1228,7 @@ fi AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[ SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper" +CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper" AC_TRY_COMPILE([ #define REPLACE_GETPASS 1 #define NO_CONFIG_H 1 @@ -1605,6 +1623,7 @@ AC_ARG_WITH(smbmount, ################################################# # check for a PAM password database +with_pam_for_crypt=no AC_MSG_CHECKING(whether to use PAM password database) AC_ARG_WITH(pam, [ --with-pam Include PAM password database support @@ -1614,6 +1633,40 @@ AC_ARG_WITH(pam, AC_MSG_RESULT(yes) AC_DEFINE(WITH_PAM) LIBS="$LIBS -lpam" + with_pam_for_crypt=yes + ;; + *) + AC_MSG_RESULT(no) + ;; + esac ], + AC_MSG_RESULT(no) +) + +# we can't build a pam module if we don't have pam. +AC_CHECK_LIB(pam, pam_get_data, [AC_DEFINE(HAVE_LIBPAM)]) + +################################################# +# check for pam_smbpass support +AC_MSG_CHECKING(whether to use pam_smbpass) +AC_ARG_WITH(pam_smbpass, +[ --with-pam_smbpass Include the smbpass PAM module + --without-pam_smbpass Don't include the smbpass PAM module (default)], +[ case "$withval" in + yes) + AC_MSG_RESULT(yes) + +# Conditions under which pam_smbpass should not be built. + + if test x$PICFLAG = x; then + AC_MSG_RESULT([No support for PIC code - disabling pam_smbpass]) + PAM_MOD="" + elif test x$ac_cv_lib_pam_pam_get_data = xno; then + AC_MSG_RESULT([No libpam found -- disabling pam_smbpass]) + PAM_MOD="" + else + AC_DEFINE(WITH_PAM_SMBPASS) + PAM_MOD="bin/pam_smbpass.so" + fi ;; *) AC_MSG_RESULT(no) @@ -1622,6 +1675,19 @@ AC_ARG_WITH(pam, AC_MSG_RESULT(no) ) + +############################################### +# test for where we get crypt() from, but only +# if not using PAM +if test $with_pam_for_crypt = no; then +AC_CHECK_FUNCS(crypt) +if test x"$ac_cv_func_crypt" = x"no"; then + AC_CHECK_LIB(crypt, crypt, [LIBS="$LIBS -lcrypt"; + AC_DEFINE(HAVE_CRYPT)]) +fi +fi + + ################################################# # removed until we get the code actually working # --jeremy @@ -1725,7 +1791,7 @@ AC_ARG_WITH(ssl, LDFLAGS="=L/usr/local/ssl/lib $LDFLAGS" ;; * ) - CFLAGS="-I${withval}/include $CFLAGS" + CFLAGS="-I${withval} $CFLAGS" LIBS="-lssl -lcrypto $LIBS" LDFLAGS="-L${withval}/lib $LDFLAGS" ;; @@ -2165,15 +2231,6 @@ samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no)]) AC_DEFINE(HAVE_ACL_GET_PERM_NP) fi fi - AC_CACHE_CHECK([for XFS ACL support],samba_cv_HAVE_XFS_ACLS,[ - AC_TRY_COMPILE([#include <sys/types.h> -#include <acl/acl.h>], -[ char test_str[13] = SGI_ACL_FILE; ], -samba_cv_HAVE_XFS_ACLS=yes,samba_cv_XFS_POSIX_ACLS=no)]) - if test x"$samba_cv_HAVE_XFS_ACLS" = x"yes"; then - AC_MSG_RESULT(Using XFS ACLs) - AC_DEFINE(HAVE_XFS_ACLS) - fi ;; esac ;; diff --git a/source/include/config.h.in b/source/include/config.h.in index 66561c9761e..15a7a856276 100644 --- a/source/include/config.h.in +++ b/source/include/config.h.in @@ -63,6 +63,7 @@ #undef HAVE_VOLATILE #undef HAVE_BROKEN_READDIR +#undef HAVE_C99_VSNPRINTF #undef HAVE_ERRNO_DECL #undef HAVE_LONGLONG #undef HAVE_OFF64_T @@ -70,6 +71,7 @@ #undef HAVE_UNSIGNED_CHAR #undef HAVE_UTIMBUF #undef HAVE_SIG_ATOMIC_T_TYPE +#undef HAVE_SOCKLEN_T_TYPE #undef ssize_t #undef ino_t #undef ssize_t @@ -124,6 +126,7 @@ #undef WITH_NISPLUS #undef WITH_TDBPWD #undef WITH_PAM +#undef WITH_PAM_SMBPASS #undef WITH_NISPLUS_HOME #undef WITH_AUTOMOUNT #undef WITH_SMBMOUNT @@ -207,9 +210,13 @@ #undef HAVE_UNIXWARE_ACLS #undef HAVE_SOLARIS_ACLS #undef HAVE_IRIX_ACLS -#undef HAVE_XFS_ACLS #undef HAVE_AIX_ACLS #undef HAVE_NO_ACLS +#undef HAVE_LIBPAM +#undef HAVE_ASPRINTF_DECL +#undef HAVE_VASPRINTF_DECL +#undef HAVE_SNPRINTF_DECL +#undef HAVE_VSNPRINTF_DECL /* The number of bytes in a int. */ #undef SIZEOF_INT @@ -430,6 +437,9 @@ /* Define if you have the _write function. */ #undef HAVE__WRITE +/* Define if you have the asprintf function. */ +#undef HAVE_ASPRINTF + /* Define if you have the atexit function. */ #undef HAVE_ATEXIT @@ -619,6 +629,9 @@ /* Define if you have the readdir64 function. */ #undef HAVE_READDIR64 +/* Define if you have the readlink function. */ +#undef HAVE_READLINK + /* Define if you have the rename function. */ #undef HAVE_RENAME @@ -697,6 +710,9 @@ /* Define if you have the strtoul function. */ #undef HAVE_STRTOUL +/* Define if you have the symlink function. */ +#undef HAVE_SYMLINK + /* Define if you have the syscall function. */ #undef HAVE_SYSCALL @@ -718,6 +734,9 @@ /* Define if you have the utimes function. */ #undef HAVE_UTIMES +/* Define if you have the vasprintf function. */ +#undef HAVE_VASPRINTF + /* Define if you have the vsnprintf function. */ #undef HAVE_VSNPRINTF @@ -727,9 +746,6 @@ /* Define if you have the yp_get_default_domain function. */ #undef HAVE_YP_GET_DEFAULT_DOMAIN -/* Define if you have the <acl/acl.h> header file. */ -#undef HAVE_ACL_ACL_H - /* Define if you have the <arpa/inet.h> header file. */ #undef HAVE_ARPA_INET_H @@ -784,6 +800,9 @@ /* Define if you have the <nss.h> header file. */ #undef HAVE_NSS_H +/* Define if you have the <nss_common.h> header file. */ +#undef HAVE_NSS_COMMON_H + /* Define if you have the <poll.h> header file. */ #undef HAVE_POLL_H @@ -808,9 +827,15 @@ /* Define if you have the <rpcsvc/ypclnt.h> header file. */ #undef HAVE_RPCSVC_YPCLNT_H +/* Define if you have the <security/_pam_macros.h> header file. */ +#undef HAVE_SECURITY__PAM_MACROS_H + /* Define if you have the <security/pam_appl.h> header file. */ #undef HAVE_SECURITY_PAM_APPL_H +/* Define if you have the <security/pam_modules.h> header file. */ +#undef HAVE_SECURITY_PAM_MODULES_H + /* Define if you have the <shadow.h> header file. */ #undef HAVE_SHADOW_H @@ -865,6 +890,9 @@ /* Define if you have the <sys/ioctl.h> header file. */ #undef HAVE_SYS_IOCTL_H +/* Define if you have the <sys/ipc.h> header file. */ +#undef HAVE_SYS_IPC_H + /* Define if you have the <sys/mman.h> header file. */ #undef HAVE_SYS_MMAN_H @@ -892,6 +920,9 @@ /* Define if you have the <sys/select.h> header file. */ #undef HAVE_SYS_SELECT_H +/* Define if you have the <sys/shm.h> header file. */ +#undef HAVE_SYS_SHM_H + /* Define if you have the <sys/socket.h> header file. */ #undef HAVE_SYS_SOCKET_H diff --git a/source/include/debug.h b/source/include/debug.h index d2c3b1d37ef..240da0d6fc5 100644 --- a/source/include/debug.h +++ b/source/include/debug.h @@ -37,21 +37,8 @@ arguemnts to DEBUG() right. We have got them wrong too often in the past. */ -#ifdef HAVE_STDARG_H -int Debug1( char *, ... ) -#ifdef __GNUC__ - __attribute__ ((format (__printf__, 1, 2))) -#endif -; -BOOL dbgtext( char *, ... ) -#ifdef __GNUC__ - __attribute__ ((format (__printf__, 1, 2))) -#endif -; -#else -int Debug1(); -BOOL dbgtext(); -#endif +int Debug1( char *, ... ) PRINTF_ATTRIBUTE(1,2); +BOOL dbgtext( char *, ... ) PRINTF_ATTRIBUTE(1,2); /* If we have these macros, we can add additional info to the header. */ #ifdef HAVE_FILE_MACRO diff --git a/source/include/includes.h b/source/include/includes.h index eef1c1e0bc1..c5f4720a5af 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -54,6 +54,13 @@ #endif #endif +/* use gcc attribute to check printf fns */ +#ifdef __GNUC__ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif + #ifdef RELIANTUNIX /* * <unistd.h> has to be included before any other to get @@ -271,10 +278,6 @@ #include <sys/acl.h> #endif -#ifdef HAVE_XFS_ACLS -#include <acl/acl.h> -#endif - #ifdef HAVE_SYS_FS_S5PARAM_H #include <sys/fs/s5param.h> #endif @@ -350,6 +353,14 @@ #endif #endif /* HAVE_NETGROUP */ +#if defined(HAVE_SYS_IPC_H) +#include <sys/ipc.h> +#endif /* HAVE_SYS_IPC_H */ + +#if defined(HAVE_SYS_SHM_H) +#include <sys/shm.h> +#endif /* HAVE_SYS_SHM_H */ + /* * Define VOLATILE if needed. */ @@ -361,15 +372,17 @@ #endif /* - * Define SIG_ATOMIC_T if needed. + * Define additional missing types */ +#ifndef HAVE_SIG_ATOMIC_T_TYPE +typedef int sig_atomic_t; +#endif -#if defined(HAVE_SIG_ATOMIC_T_TYPE) -#define SIG_ATOMIC_T sig_atomic_t -#else -#define SIG_ATOMIC_T int +#ifndef HAVE_SOCKLEN_T_TYPE +typedef int socklen_t; #endif + #ifndef uchar #define uchar unsigned char #endif @@ -421,6 +434,9 @@ #define int32 long #elif (SIZEOF_SHORT == 4) #define int32 short +#else +/* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */ +#define uint32 int #endif #endif @@ -436,6 +452,9 @@ #define uint32 unsigned long #elif (SIZEOF_SHORT == 4) #define uint32 unsigned short +#else +/* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */ +#define uint32 unsigned #endif #endif @@ -622,6 +641,8 @@ extern int errno; #include "messages.h" #include "util_list.h" +#include "util_getent.h" + #ifndef UBI_BINTREE_H #include "ubi_Cache.h" #endif /* UBI_BINTREE_H */ @@ -644,6 +665,8 @@ extern int errno; #include "profile.h" +#include "mapping.h" + #ifndef MAXCODEPAGELINES #define MAXCODEPAGELINES 256 #endif @@ -678,17 +701,38 @@ typedef struct smb_wpasswd { #define UNI_XDIGIT 0x8 #define UNI_SPACE 0x10 -#ifdef HAVE_NSS_H +#ifdef HAVE_NSS_COMMON_H + +/* Sun Solaris */ + +#include <nss_common.h> +#include <nss_dbdefs.h> +#include <nsswitch.h> + +typedef nss_status_t NSS_STATUS; + +#define NSS_STATUS_SUCCESS NSS_SUCCESS +#define NSS_STATUS_NOTFOUND NSS_NOTFOUND +#define NSS_STATUS_UNAVAIL NSS_UNAVAIL +#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN + +#elif HAVE_NSS_H + +/* GNU */ + #include <nss.h> -#else -/* Minimal needed to compile.. */ +typedef enum nss_status NSS_STATUS; + +#else /* Nothing's defined. Neither gnu nor sun */ -enum nss_status { - NSS_STATUS_SUCCESS, - NSS_STATUS_NOTFOUND, - NSS_STATUS_UNAVAIL -}; +typedef enum +{ + NSS_STATUS_SUCCESS, + NSS_STATUS_NOTFOUND, + NSS_STATUS_UNAVAIL, + NSS_STATUS_TRYAGAIN +} NSS_STATUS; #endif @@ -846,6 +890,9 @@ int setresuid(uid_t ruid, uid_t euid, uid_t suid); #if (defined(USE_SETRESUID) && !defined(HAVE_SETRESGID_DECL)) int setresgid(gid_t rgid, gid_t egid, gid_t sgid); #endif +#ifndef HAVE_VASPRINTF_DECL +int vasprintf(char **ptr, const char *format, va_list ap); +#endif #if !defined(HAVE_BZERO) && defined(HAVE_MEMSET) #define bzero(a,b) memset((a),'\0',(b)) @@ -934,13 +981,13 @@ int setresgid(gid_t rgid, gid_t egid, gid_t sgid); #define S_IXOTH 00001 /* execute permission: other */ #endif -/* Some systems (SCO) treat UNIX domain sockets as FIFOs */ - -#ifndef S_IFSOCK -#define S_IFSOCK S_IFIFO +/* NetBSD doesn't have these */ +#ifndef SHM_R +#define SHM_R 0400 #endif -#ifndef S_ISSOCK -#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK) + +#ifndef SHM_W +#define SHM_W 0200 #endif #if HAVE_KERNEL_SHARE_MODES @@ -982,5 +1029,19 @@ extern int DEBUGLEVEL; #define RTLD_NOW 0 #endif +/* add varargs prototypes with printf checking */ +int fdprintf(int , char *, ...) PRINTF_ATTRIBUTE(2,3); +#ifndef HAVE_SNPRINTF_DECL +int snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4); +#endif +#ifndef HAVE_ASPRINTF_DECL +int asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); +#endif + +/* we used to use these fns, but now we have good replacements + for snprintf and vsnprintf */ +#define slprintf snprintf +#define vslprintf vsnprintf + #endif /* _INCLUDES_H */ diff --git a/source/include/local.h b/source/include/local.h index b5590f9f912..1a58e9e2d11 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -100,6 +100,11 @@ #define GUEST_ACCOUNT "nobody" #endif +/* user to test password server with as invalid in security=server mode. */ +#ifndef INVALID_USER_PREFIX +#define INVALID_USER_PREFIX "sambatest" +#endif + /* the default pager to use for the client "more" command. Users can override this with the PAGER environment variable */ #ifndef PAGER @@ -176,4 +181,12 @@ /* Minimum length of allowed password when changing UNIX password. */ #define MINPASSWDLENGTH 5 +/* maximum ID number used for session control. This cannot be larger + than 62*62 for the current code */ +#define MAX_SESSION_ID 3000 + +#ifndef SESSION_TEMPLATE +#define SESSION_TEMPLATE "smb/%d" +#endif + #endif diff --git a/source/include/messages.h b/source/include/messages.h index fb88ddbd0e1..b41f1f38a8e 100644 --- a/source/include/messages.h +++ b/source/include/messages.h @@ -39,5 +39,6 @@ #define MSG_PRINTER_NOTIFY 2001 #define MSG_SMB_CONF_UPDATED 3001 +#define MSG_SMB_FORCE_TDIS 3002 #endif diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h index ecd261949c5..58ed1759e71 100644 --- a/source/include/ntdomain.h +++ b/source/include/ntdomain.h @@ -267,7 +267,8 @@ typedef struct struct acct_info { fstring acct_name; /* account name */ - uint32 smb_userid; /* domain-relative RID */ + fstring acct_desc; /* account name */ + uint32 rid; /* domain-relative RID */ }; /* diff --git a/source/include/profile.h b/source/include/profile.h index 5916614fb74..a8ffb963671 100644 --- a/source/include/profile.h +++ b/source/include/profile.h @@ -96,6 +96,10 @@ struct profile_stats { unsigned syscall_ftruncate_time; unsigned syscall_fcntl_lock_count; unsigned syscall_fcntl_lock_time; + unsigned syscall_readlink_count; + unsigned syscall_readlink_time; + unsigned syscall_symlink_count; + unsigned syscall_symlink_time; /* stat cache counters */ unsigned statcache_lookups; unsigned statcache_misses; diff --git a/source/include/proto.h b/source/include/proto.h index ba66888ea3c..c1e3a4fe12d 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -100,7 +100,8 @@ int sys_fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize); /*The following definitions come from lib/genrand.c */ -void generate_random_buffer( unsigned char *out, int len, BOOL re_seed); +void set_rand_reseed_data(unsigned char *data, size_t len); +void generate_random_buffer( unsigned char *out, int len, BOOL do_reseed_now); char *generate_random_str(size_t len); /*The following definitions come from lib/getsmbpass.c */ @@ -110,11 +111,10 @@ char *getsmbpass(char *prompt) ; /*The following definitions come from lib/hash.c */ BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compare_func); -int string_hash(int hash_size, const char *key); hash_element *hash_lookup(hash_table *table, char *key); hash_element *hash_insert(hash_table *table, char *value, char *key); void hash_remove(hash_table *table, hash_element *hash_elem); -BOOL hash_clear(hash_table *table); +void hash_clear(hash_table *table); /*The following definitions come from lib/interface.c */ @@ -158,7 +158,7 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, void *buf, size_t len /*The following definitions come from lib/ms_fnmatch.c */ -int ms_fnmatch(char *pattern, char *string); +int ms_fnmatch(const char *pattern, const char *string); /*The following definitions come from lib/pidfile.c */ @@ -188,10 +188,6 @@ void CatchSignal(int signum,void (*handler)(int )); void CatchChild(void); void CatchChildLeaveStatus(void); -/*The following definitions come from lib/slprintf.c */ - -int vslprintf(char *str, int n, char *format, va_list ap); - /*The following definitions come from libsmb/cliconnect.c */ BOOL cli_session_setup(struct cli_state *cli, @@ -223,6 +219,7 @@ int cli_set_port(struct cli_state *cli, int port); BOOL cli_receive_smb(struct cli_state *cli); BOOL cli_send_smb(struct cli_state *cli); void cli_setup_packet(struct cli_state *cli); +void cli_setup_bcc(struct cli_state *cli, void *p); void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr); struct cli_state *cli_initialise(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); @@ -241,10 +238,10 @@ BOOL cli_unlink(struct cli_state *cli, char *fname); BOOL cli_mkdir(struct cli_state *cli, char *dname); BOOL cli_rmdir(struct cli_state *cli, char *dname); int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag); -int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, uint32 FileAttributes, - uint32 ShareAccess, uint32 CreateDisposition, uint32 CreateOptions); +int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, + uint32 FileAttributes, uint32 ShareAccess, + uint32 CreateDisposition, uint32 CreateOptions); int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess); -int cli_nt_create_uni(struct cli_state *cli, char *fname, uint32 DesiredAccess); int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); BOOL cli_close(struct cli_state *cli, int fnum); BOOL cli_lock(struct cli_state *cli, int fnum, @@ -261,34 +258,39 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); BOOL cli_chkpath(struct cli_state *cli, char *path); BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path); /*The following definitions come from libsmb/clilist.c */ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)); +int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state); int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)); + void (*fn)(file_info *, const char *, void *), void *state); +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state); /*The following definitions come from libsmb/cli_lsarpc.c */ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds); void cli_lsa_shutdown(struct cli_state *cli); -uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, - uint32 des_access, POLICY_HND *pol); -uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol); -uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, - int num_sids, DOM_SID *sids, char ***names, - uint32 **types, int *num_names); -uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, - int num_names, char **names, DOM_SID **sids, - uint32 **types, int *num_sids); -uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, - uint16 info_class, fstring domain_name, - DOM_SID * domain_sid); -uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, - uint32 *enum_ctx, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids); +uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL sec_qos, uint32 des_access, POLICY_HND *pol); +uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol); +uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_sids, DOM_SID *sids, + char ***names, uint32 **types, int *num_names); +uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_names, char **names, + DOM_SID **sids, uint32 **types, int *num_sids); +uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint16 info_class, + fstring domain_name, DOM_SID *domain_sid); +uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *enum_ctx, + uint32 *num_domains, char ***domain_names, + DOM_SID **domain_sids); /*The following definitions come from libsmb/climessage.c */ @@ -297,6 +299,15 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); BOOL cli_message_end(struct cli_state *cli, int grp); +/*The following definitions come from libsmb/cli_netlogon.c */ + +struct cli_state *cli_netlogon_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds); +void cli_netlogon_shutdown(struct cli_state *cli); +uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 query_level); + /*The following definitions come from libsmb/cliprint.c */ int cli_print_queue(struct cli_state *cli, @@ -305,7 +316,7 @@ int cli_printjob_del(struct cli_state *cli, int job); /*The following definitions come from libsmb/clirap.c */ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, char *data, uint32 data_count, uint32 max_data_count, @@ -317,9 +328,10 @@ BOOL cli_api(struct cli_state *cli, char **rparam, int *rprcnt, char **rdata, int *rdrcnt); BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state); BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)); + void (*fn)(const char *, uint32, const char *, void *), + void *state); BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password); BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, @@ -333,10 +345,11 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino); +BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata); /*The following definitions come from libsmb/clireadwrite.c */ -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); +ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, char *buf, off_t offset, size_t size); @@ -348,30 +361,53 @@ ssize_t cli_smbwrite(struct cli_state *cli, struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds); void cli_samr_shutdown(struct cli_state *cli); -uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, - uint32 access_mask, POLICY_HND *connect_pol); -uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol); -uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, - uint32 access_mask, DOM_SID *domain_sid, - POLICY_HND *domain_pol); -uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, - uint32 access_mask, uint32 user_rid, - POLICY_HND *user_pol); -uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, - uint32 access_mask, uint32 group_rid, - POLICY_HND *group_pol); -uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, - uint16 switch_value, SAM_USERINFO_CTR *ctr); -uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, - uint32 info_level, GROUP_INFO_CTR *ctr); -uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, - uint32 *num_groups, DOM_GID **gid); -uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, - uint32 *num_mem, uint32 **rid, uint32 **attr); +uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *srv_name, uint32 access_mask, + POLICY_HND *connect_pol); +uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol); +uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol, uint32 access_mask, + DOM_SID *domain_sid, POLICY_HND *domain_pol); +uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 user_rid, POLICY_HND *user_pol); +uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 group_rid, POLICY_HND *group_pol); +uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + SAM_USERINFO_CTR *ctr); +uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 info_level, + GROUP_INFO_CTR *ctr); +uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint32 *num_groups, + DOM_GID **gid); +uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 *num_mem, + uint32 **rid, uint32 **attr); +uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *start_idx, + uint32 size, struct acct_info **dom_groups, + uint32 *num_dom_groups); +uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *alias_pol, uint32 *num_mem, + DOM_SID **sids); +uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 alias_rid, POLICY_HND *alias_pol); +uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint16 switch_value, + SAM_UNK_CTR *ctr); +uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 *start_idx, + uint16 switch_value, uint32 *num_entries, + uint32 max_entries, SAM_DISPINFO_CTR *ctr); /*The following definitions come from libsmb/clisecdesc.c */ -SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd); +SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx); BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd); /*The following definitions come from libsmb/cli_spoolss.c */ @@ -380,24 +416,46 @@ struct cli_state *cli_spoolss_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds); void cli_spoolss_shutdown(struct cli_state *cli); -uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, - char *datatype, uint32 access_required, - char *station, char *username, - POLICY_HND *pol); -uint32 cli_spoolss_close_printer(struct cli_state *cli, POLICY_HND *pol); -uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, - uint32 level, int *returned, - PRINTER_INFO_CTR *ctr); -uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, - int *returned, PORT_INFO_CTR *ctr); +uint32 cli_spoolss_open_printer_ex( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *printername, + char *datatype, + uint32 access_required, + char *station, + char *username, + POLICY_HND *pol +); +uint32 cli_spoolss_close_printer( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol +); +uint32 cli_spoolss_enum_printers( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 flags, + uint32 level, + int *returned, + PRINTER_INFO_CTR *ctr +); +uint32 cli_spoolss_enum_ports( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 level, + int *returned, + PORT_INFO_CTR *ctr +); uint32 cli_spoolss_getprinter( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr ); uint32 cli_spoolss_setprinter( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr, @@ -405,6 +463,7 @@ uint32 cli_spoolss_setprinter( ); uint32 cli_spoolss_getprinterdriver ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, char* env, @@ -412,6 +471,7 @@ uint32 cli_spoolss_getprinterdriver ( ); uint32 cli_spoolss_enumprinterdrivers ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, char* env, uint32 *returned, @@ -419,25 +479,50 @@ uint32 cli_spoolss_enumprinterdrivers ( ); uint32 cli_spoolss_getprinterdriverdir ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, char* env, DRIVER_DIRECTORY_CTR *ctr ); uint32 cli_spoolss_addprinterdriver ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, PRINTER_DRIVER_CTR *ctr ); uint32 cli_spoolss_addprinterex ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR *ctr ); +uint32 cli_spoolss_deleteprinterdriver ( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *arch, + char *driver +); + +/*The following definitions come from libsmb/cli_srvsvc.c */ + +struct cli_state *cli_svrsvc_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds); +void cli_srvsvc_shutdown(struct cli_state *cli); +uint32 cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 switch_value, SRV_INFO_CTR *ctr); + +/*The following definitions come from libsmb/clistr.c */ + +int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags); +int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags); +int clistr_align_out(struct cli_state *cli, const void *p, int flags); +int clistr_align_in(struct cli_state *cli, const void *p, int flags); /*The following definitions come from libsmb/clitrans.c */ BOOL cli_send_trans(struct cli_state *cli, int trans, - char *name, int pipe_name_len, + char *pipe_name, int fid, int flags, uint16 *setup, int lsetup, int msetup, char *param, int lparam, int mparam, @@ -475,12 +560,17 @@ BOOL deal_with_creds(uchar sess_key[8], struct node_status *name_status_query(int fd,struct nmb_name *name, struct in_addr to_ip, int *num_names); BOOL name_status_find(int type, struct in_addr to_ip, char *name); +BOOL name_register(int fd, const char *name, int name_type, + struct in_addr name_ip, int opcode, + BOOL bcast, + struct in_addr to_ip, int *count); struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, struct in_addr to_ip, int *count); FILE *startlmhosts(char *fname); BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); void endlmhosts(FILE *fp); +BOOL name_register_wins(const char *name, int name_type); BOOL name_resolve_bcast(const char *name, int name_type, struct in_addr **return_ip_list, int *return_count); BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); @@ -608,8 +698,9 @@ int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual); int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); int sys_acl_valid( SMB_ACL_T theacl ); -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); +int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); int sys_acl_set_fd( int fd, SMB_ACL_T theacl); +int sys_acl_delete_def_file(const char *name); int sys_acl_free_text(char *text); int sys_acl_free_acl(SMB_ACL_T the_acl) ; int sys_acl_free_qualifier(void *qual) ; @@ -629,8 +720,9 @@ int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type); int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p); int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d); int sys_acl_valid(SMB_ACL_T acl_d); -int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d); +int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d); int sys_acl_set_fd(int fd, SMB_ACL_T acl_d); +int sys_acl_delete_def_file(const char *path); int sys_acl_free_text(char *text); int sys_acl_free_acl(SMB_ACL_T acl_d) ; int sys_acl_free_qualifier(void *qual) ; @@ -650,32 +742,12 @@ int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type); int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p); int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d); int sys_acl_valid(SMB_ACL_T acl_d); -int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d); +int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d); int sys_acl_set_fd(int fd, SMB_ACL_T acl_d); +int sys_acl_delete_def_file(const char *name); int sys_acl_free_text(char *text); int sys_acl_free_acl(SMB_ACL_T acl_d) ; int sys_acl_free_qualifier(void *qual) ; -int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p); -SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type); -SMB_ACL_T sys_acl_get_fd(int fd); -char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen); -int sys_acl_valid( SMB_ACL_T theacl ); -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); -int sys_acl_set_fd( int fd, SMB_ACL_T theacl); -int sys_acl_create_entry( SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p); -int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); -int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); -void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d); -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset); -int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); -int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); -SMB_ACL_T sys_acl_init( int count); -int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type); -int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry_d, void *qual_p); -int sys_acl_set_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d); -int sys_acl_free_text(char *text); -int sys_acl_free_acl(SMB_ACL_T the_acl) ; -int sys_acl_free_qualifier(void *qual) ; int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); @@ -691,8 +763,9 @@ int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual); int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); int sys_acl_valid( SMB_ACL_T theacl ); -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); +int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); int sys_acl_set_fd( int fd, SMB_ACL_T theacl); +int sys_acl_delete_def_file(const char *name); int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); int sys_acl_free_text(char *text); int sys_acl_free_acl(SMB_ACL_T posix_acl); @@ -714,8 +787,9 @@ int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual); int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); int sys_acl_valid( SMB_ACL_T theacl ); -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); +int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); int sys_acl_set_fd( int fd, SMB_ACL_T theacl); +int sys_acl_delete_def_file(const char *name); int sys_acl_free_acl(SMB_ACL_T the_acl) ; int sys_acl_free_qualifier(void *qual) ; @@ -735,6 +809,8 @@ FILE *sys_fopen(const char *path, const char *type); SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp); int sys_waitpid(pid_t pid,int *status,int options); char *sys_getwd(char *s); +int sys_symlink(const char *oldpath, const char *newpath); +int sys_readlink(const char *path, char *buf, size_t bufsiz); int sys_chown(const char *fname,uid_t uid,gid_t gid); int sys_chroot(const char *dname); struct hostent *sys_gethostbyname(const char *name); @@ -770,11 +846,13 @@ int sys_dlclose (void *handle); TALLOC_CTX *talloc_init(void); void *talloc(TALLOC_CTX *t, size_t size); +void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size); void talloc_destroy_pool(TALLOC_CTX *t); void talloc_destroy(TALLOC_CTX *t); size_t talloc_pool_size(TALLOC_CTX *t); void *talloc_zero(TALLOC_CTX *t, size_t size); void *talloc_memdup(TALLOC_CTX *t, void *p, size_t size); +char *talloc_strdup(TALLOC_CTX *t, char *p); /*The following definitions come from lib/time.c */ @@ -799,7 +877,7 @@ time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs); /*The following definitions come from lib/ufc.c */ -char *ufc_crypt(char *key,char *salt); +char *ufc_crypt(const char *key,const char *salt); /*The following definitions come from lib/username.c */ @@ -842,6 +920,8 @@ char *attrib_string(uint16 mode); void show_msg(char *buf); void smb_setlen(char *buf,int len); int set_message(char *buf,int num_words,int num_bytes,BOOL zero); +void set_message_bcc(char *buf,int num_bytes); +void set_message_end(void *outbuf,void *end_ptr); void dos_clean_name(char *s); void unix_clean_name(char *s); void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date); @@ -862,7 +942,6 @@ BOOL zero_ip(struct in_addr ip); char *automount_lookup(char *user_name); char *automount_lookup(char *user_name); BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask); -struct hostent *Get_Hostbyname(const char *name); BOOL process_exists(pid_t pid); char *uidtoname(uid_t uid); char *gidtoname(gid_t gid); @@ -886,7 +965,6 @@ int str_checksum(const char *s); void zero_free(void *p, size_t size); int set_maxfiles(int requested_max); BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name); -char *smbd_mktemp(char *template); int smb_mkstemp(char *template); void *memdup(void *p, size_t size); char *myhostname(void); @@ -917,6 +995,13 @@ char **file_lines_pload(char *syscmd, int *numlines, BOOL convert); void file_lines_free(char **lines); void file_lines_slashcont(char **lines); +/*The following definitions come from lib/util_getent.c */ + +struct sys_grent * getgrent_list(void); +void grent_free (struct sys_grent *glist); +struct sys_pwent * getpwent_list(void); +void pwent_free (struct sys_pwent *plist); + /*The following definitions come from lib/util_list.c */ BOOL copy_policy_hnd (POLICY_HND *dest, const POLICY_HND *src); @@ -937,6 +1022,8 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, /*The following definitions come from lib/util_sec.c */ +void sec_init(void); +BOOL non_root_mode(void); void gain_root_privilege(void); void gain_root_group_privilege(void); void set_effective_uid(uid_t uid); @@ -957,6 +1044,7 @@ char *sid_to_string(fstring sidstr_out, DOM_SID *sid); BOOL string_to_sid(DOM_SID *sidout, char *sidstr); BOOL sid_append_rid(DOM_SID *sid, uint32 rid); BOOL sid_split_rid(DOM_SID *sid, uint32 *rid); +BOOL sid_peek_rid(DOM_SID *sid, uint32 *rid); void sid_copy(DOM_SID *dst, const DOM_SID *src); DOM_SID *sid_dup(DOM_SID *src); BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid); @@ -978,12 +1066,10 @@ ssize_t write_socket(int fd,char *buf,size_t len); ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout); BOOL receive_smb(int fd,char *buffer, unsigned int timeout); BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout); -BOOL send_null_session_msg(int fd); BOOL send_smb(int fd,char *buffer); BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type); int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind); int open_socket_out(int type, struct in_addr *addr, int port ,int timeout); -void reset_globals_after_fork(void); void client_setfd(int fd); char *client_name(void); char *client_addr(void); @@ -992,6 +1078,7 @@ char *get_socket_addr(int fd); int open_pipe_sock(char *path); int create_pipe_socket(char *dir, int dir_perms, char *path, int path_perms); +int sock_exec(const char *prog); /*The following definitions come from lib/util_str.c */ @@ -1127,6 +1214,7 @@ unsigned long wins_srv_count( void ); /*The following definitions come from locking/brlock.c */ void brl_init(int read_only); +void brl_shutdown(int read_only); BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, @@ -1137,7 +1225,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum brl_type lock_type); + enum brl_type lock_type, int check_self); void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum); int brl_forall(BRLOCK_FN(fn)); @@ -1145,11 +1233,11 @@ int brl_forall(BRLOCK_FN(fn)); BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_BIG_UINT count,SMB_BIG_UINT offset, - enum brl_type lock_type); -BOOL do_lock(files_struct *fsp,connection_struct *conn, + enum brl_type lock_type, BOOL check_self); +BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, int *eclass,uint32 *ecode); -BOOL do_unlock(files_struct *fsp,connection_struct *conn, +BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset, int *eclass,uint32 *ecode); void locking_close_file(files_struct *fsp); @@ -1189,15 +1277,11 @@ BOOL is_msdfs_link(connection_struct* conn, char* path); BOOL get_referred_path(struct junction_map* junction); BOOL dfs_redirect(char* pathname, connection_struct* conn); BOOL dfs_findfirst_redirect(char* pathname, connection_struct* conn); -int setup_dfs_referral(char* pathname, int max_referral_level, - char** ppdata); +int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata); int dfs_path_error(char* inbuf, char* outbuf); BOOL create_msdfs_link(struct junction_map* jn, BOOL exists); BOOL remove_msdfs_link(struct junction_map* jn); int enum_msdfs_links(struct junction_map* jn); -int setup_dfs_referral(char* pathname, int max_referral_level, - char** ppdata); -BOOL is_msdfs_link(connection_struct* conn, char* path); /*The following definitions come from nmbd/asyncdns.c */ @@ -1563,9 +1647,6 @@ void close_sock(void); int write_sock(void *buffer, int count); int read_reply(struct winbindd_response *response); void free_response(struct winbindd_response *response); -enum nss_status winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response); /*The following definitions come from param/loadparm.c */ @@ -1583,8 +1664,7 @@ char *lp_os2_driver_map(void); char *lp_lockdir(void); char *lp_utmpdir(void); char *lp_wtmpdir(void); -char *lp_utmp_hostname(void); -BOOL lp_utmp_consolidate(void); +BOOL lp_utmp(void); char *lp_rootdir(void); char *lp_source_environment(void); char *lp_defaultservice(void); @@ -1614,11 +1694,8 @@ char *lp_panic_action(void); char *lp_adduser_script(void); char *lp_deluser_script(void); char *lp_wins_hook(void); -char *lp_domain_groups(void); char *lp_domain_admin_group(void); char *lp_domain_guest_group(void); -char *lp_domain_admin_users(void); -char *lp_domain_guest_users(void); char *lp_winbind_uid(void); char *lp_winbind_gid(void); char *lp_template_homedir(void); @@ -1659,8 +1736,10 @@ BOOL lp_use_rhosts(void); BOOL lp_readprediction(void); BOOL lp_readbmpx(void); BOOL lp_readraw(void); +BOOL lp_large_readwrite(void); BOOL lp_writeraw(void); BOOL lp_null_passwords(void); +BOOL lp_obey_pam_restrictions(void); BOOL lp_strip_dot(void); BOOL lp_encrypted_passwords(void); BOOL lp_update_encrypted(void); @@ -1670,9 +1749,9 @@ BOOL lp_debug_hires_timestamp(void); BOOL lp_debug_pid(void); BOOL lp_debug_uid(void); BOOL lp_browse_list(void); -BOOL lp_unix_realname(void); BOOL lp_nis_home_map(void); BOOL lp_bind_interfaces_only(void); +BOOL lp_pam_password_change(void); BOOL lp_unix_password_sync(void); BOOL lp_passwd_chat_debug(void); BOOL lp_nt_smb_support(void); @@ -1684,6 +1763,7 @@ BOOL lp_restrict_anonymous(void); BOOL lp_lanman_auth(void); BOOL lp_host_msdfs(void); BOOL lp_kernel_oplocks(void); +BOOL lp_enhanced_browsing(void); int lp_os_level(void); int lp_max_ttl(void); int lp_max_wins_ttl(void); @@ -1762,6 +1842,7 @@ BOOL lp_shortpreservecase(int ); BOOL lp_casemangle(int ); BOOL lp_status(int ); BOOL lp_hide_dot_files(int ); +BOOL lp_hideunreadable(int ); BOOL lp_browseable(int ); BOOL lp_readonly(int ); BOOL lp_no_set_dir(int ); @@ -1774,7 +1855,6 @@ BOOL lp_map_archive(int ); BOOL lp_locking(int ); BOOL lp_strict_locking(int ); BOOL lp_posix_locking(int ); -BOOL lp_utmp(int ); BOOL lp_share_modes(int ); BOOL lp_oplocks(int ); BOOL lp_level2_oplocks(int ); @@ -1796,12 +1876,12 @@ BOOL lp_blocking_locks(int ); BOOL lp_inherit_perms(int ); int lp_create_mask(int ); int lp_force_create_mode(int ); -int _lp_security_mask(int ); -int _lp_force_security_mode(int ); +int lp_security_mask(int ); +int lp_force_security_mode(int ); int lp_dir_mask(int ); int lp_force_dir_mode(int ); -int _lp_dir_security_mask(int ); -int _lp_force_dir_security_mode(int ); +int lp_dir_security_mask(int ); +int lp_force_dir_security_mode(int ); int lp_max_connections(int ); int lp_defaultcase(int ); int lp_minprintspace(int ); @@ -1843,10 +1923,6 @@ int lp_default_server_announce(void); int lp_major_announce_version(void); int lp_minor_announce_version(void); void lp_set_name_resolve_order(char *new_order); -int lp_security_mask(int snum); -int lp_force_security_mode(int snum); -int lp_dir_security_mask(int snum); -int lp_force_dir_security_mode(int snum); char *lp_printername(int snum); /*The following definitions come from param/params.c */ @@ -1865,9 +1941,11 @@ struct passdb_ops *nisplus_initialize_password_db(void); /*The following definitions come from passdb/pampass.c */ -BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty); -BOOL pam_accountcheck(char * user); -BOOL pam_passcheck(char * user, char * password); +BOOL smb_pam_claim_session(char *user, char *tty, char *rhost); +BOOL smb_pam_close_session(char *user, char *tty, char *rhost); +uint32 smb_pam_accountcheck(char * user); +uint32 smb_pam_passcheck(char * user, char * password); +BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword); /*The following definitions come from passdb/pass_check.c */ @@ -1942,6 +2020,7 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16], time_t *pass_last_set_time); BOOL secrets_store_trust_account_password(char *domain, uint8 new_pwd[16]); BOOL trust_password_delete(char *domain); +void reset_globals_after_fork(void); /*The following definitions come from passdb/smbpass.c */ @@ -2010,6 +2089,8 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, fstring printername, fstring architecture, uint32 version); uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); +BOOL printer_driver_in_use (char *arch, char *driver); +uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i); BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index, fstring value, uint8 **data, uint32 *type, uint32 *len); BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, @@ -2031,7 +2112,7 @@ void pcap_printer_fn(void (*fn)(char *, char *)); /*The following definitions come from printing/printfsp.c */ -files_struct *print_fsp_open(connection_struct *conn,char *jobname); +files_struct *print_fsp_open(connection_struct *conn); void print_fsp_end(files_struct *fsp, BOOL normal_close); /*The following definitions come from printing/print_generic.c */ @@ -2166,6 +2247,9 @@ void cli_use_wait_keyboard(void); /*The following definitions come from rpcclient/cmd_lsarpc.c */ +/*The following definitions come from rpcclient/cmd_netlogon.c */ + + /*The following definitions come from rpcclient/cmd_samr.c */ @@ -2174,6 +2258,9 @@ void cli_use_wait_keyboard(void); BOOL get_short_archi(char *short_archi, char *long_archi); void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch); +/*The following definitions come from rpcclient/cmd_srvsvc.c */ + + /*The following definitions come from rpc_client/ncacn_np_use.c */ BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name, @@ -2297,7 +2384,6 @@ void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context, uint32 status); BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth); -void lsa_free_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e); BOOL lsa_io_dom_query_5(char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth); BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth); @@ -2321,6 +2407,8 @@ BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth); BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth); BOOL lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET *q_c, prs_struct *ps, int depth); BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, int depth); +BOOL lsa_io_q_unk_get_connuser(char *desc, LSA_Q_UNK_GET_CONNUSER *q_c, prs_struct *ps, int depth); +BOOL lsa_io_r_unk_get_connuser(char *desc, LSA_R_UNK_GET_CONNUSER *r_c, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_misc.c */ @@ -2391,16 +2479,28 @@ void init_owf_info(OWF_INFO *hash, uint8 data[16]); BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth); BOOL smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth); BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth); +void init_unistr3(UNISTR3 *str, const char *buf); BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth); BOOL prs_uint64(char *name, prs_struct *ps, int depth, UINT64_S *data64); /*The following definitions come from rpc_parse/parse_net.c */ BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth); -void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level, - uint32 flags, uint32 pdc_status, uint32 logon_attempts, - uint32 tc_status, char *trusted_domain_name); +void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, char *srv_name, + uint32 query_level); +void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level, + uint32 flags, uint32 pdc_status, + uint32 logon_attempts, uint32 tc_status, + char *trusted_domain_name); BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth); +BOOL net_io_q_logon_ctrl(char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps, + int depth); +void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, char *srv_name, + uint32 query_level); +void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level, + uint32 flags, uint32 pdc_status); +BOOL net_io_r_logon_ctrl(char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps, + int depth); void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t, uint32 num_doms, char *dom_name); BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth); @@ -2410,6 +2510,8 @@ void init_q_req_chal(NET_Q_REQ_CHAL *q_c, DOM_CHAL *clnt_chal); BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth); BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth); +BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth); +BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth); void init_q_auth_2(NET_Q_AUTH_2 *q_a, char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name, DOM_CHAL *clnt_chal, uint32 clnt_flgs); @@ -2715,19 +2817,19 @@ void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND *pol, uint32 max_entries); BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e, prs_struct *ps, int depth); -void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); -void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); -void init_sam_dispinfo_3(SAM_DISPINFO_3 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, DOMAIN_GRP * grp); -void init_sam_dispinfo_4(SAM_DISPINFO_4 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); -void init_sam_dispinfo_5(SAM_DISPINFO_5 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, DOMAIN_GRP * grp); void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u, @@ -2873,7 +2975,7 @@ BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid, BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u, prs_struct *ps, int depth); void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, POLICY_HND *pol, - uint32 unknown_0, uint32 rid); + uint32 access_mask, uint32 rid); BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS * q_u, prs_struct *ps, int depth); BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS * r_u, @@ -2928,12 +3030,12 @@ void init_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u, uint32 status); BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u, prs_struct *ps, int depth); -void init_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u, +uint32 init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u, POLICY_HND *pol, uint32 flags, uint32 num_names, char **name); BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u, prs_struct *ps, int depth); -void init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u, +uint32 init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u, uint32 num_rids, uint32 *rid, uint32 *type, uint32 status); @@ -2971,8 +3073,7 @@ void init_sam_user_info11(SAM_USER_INFO_11 * usr, NTTIME * expiry, char *mach_acct, uint32 rid_user, uint32 rid_group, uint16 acct_ctrl); -void init_sam_user_info24(SAM_USER_INFO_24 * usr, - char newpass[516], uint16 passlen); +void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516]); void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all zeros */ NTTIME * logoff_time, /* all zeros */ NTTIME * kickoff_time, /* all zeros */ @@ -3159,6 +3260,7 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, const fstring clientname, const fstring user_name); BOOL make_spoolss_q_addprinterex( + TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, const char *srv_name, const char* clientname, @@ -3166,10 +3268,18 @@ BOOL make_spoolss_q_addprinterex( uint32 level, PRINTER_INFO_CTR *ctr); BOOL make_spoolss_printer_info_2( + TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, PRINTER_INFO_2 *info ); BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth); +BOOL make_spoolss_q_deleteprinterdriver( + TALLOC_CTX *mem_ctx, + SPOOL_Q_DELETEPRINTERDRIVER *q_u, + const char *server, + const char* arch, + const char* driver +); BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, const POLICY_HND *handle, @@ -3183,6 +3293,8 @@ BOOL spoolss_io_q_abortprinter(char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct BOOL spoolss_io_r_abortprinter(char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_deleteprinter(char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_deleteprinter(char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_deleteprinterdriver(char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_deleteprinterdriver(char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth); @@ -3247,9 +3359,14 @@ BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, NEW_BUFFER *buffer, uint32 offered); BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth); -BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, - fstring servername, uint32 level, - NEW_BUFFER *buffer, uint32 offered); +BOOL make_spoolss_q_enumprinters( + SPOOL_Q_ENUMPRINTERS *q_u, + uint32 flags, + fstring servername, + uint32 level, + NEW_BUFFER *buffer, + uint32 offered +); BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, fstring servername, uint32 level, NEW_BUFFER *buffer, uint32 offered); @@ -3258,6 +3375,7 @@ BOOL spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); BOOL make_spoolss_q_getprinter( + TALLOC_CTX *mem_ctx, SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, @@ -3265,6 +3383,7 @@ BOOL make_spoolss_q_getprinter( uint32 offered ); BOOL make_spoolss_q_setprinter( + TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, @@ -3316,15 +3435,22 @@ BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_ BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth); BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth); BOOL make_spoolss_q_addprinterdriver( + TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, uint32 level, PRINTER_DRIVER_CTR *info); BOOL make_spoolss_driver_info_3( + TALLOC_CTX *mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info, DRIVER_INFO_3 *info3 ); -BOOL make_spoolss_buffer5(BUFFER5 *buf5, uint32 len, uint16 *src); +BOOL make_spoolss_buffer5( + TALLOC_CTX *mem_ctx, + BUFFER5 *buf5, + uint32 len, + uint16 *src +); BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni, @@ -3340,6 +3466,8 @@ BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_addprintprocessor(char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_addprintprocessor(char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth); @@ -3393,7 +3521,8 @@ void init_srv_share_info502(SH_INFO_502 *sh502, char *net_name, uint32 type, char *remark, uint32 perms, uint32 max_uses, uint32 num_uses, char *path, char *passwd, SEC_DESC *psd, size_t sd_size); -void init_srv_share_info502_str(SH_INFO_502_STR *sh502, +void init_srv_share_info502_str(SH_INFO_502_STR *sh502str, + SH_INFO_502 *ptrs, char *net_name, char *remark, char *path, char *passwd, SEC_DESC *psd, size_t sd_size); void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, @@ -3461,13 +3590,27 @@ void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv, BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth); void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv, uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status); +void init_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv, + uint32 switch_value, uint32 status); +BOOL srv_io_q_net_srv_set_info(char *desc, SRV_Q_NET_SRV_SET_INFO *q_n, + prs_struct *ps, int depth); BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth); +BOOL srv_io_r_net_srv_set_info(char *desc, SRV_R_NET_SRV_SET_INFO *r_n, + prs_struct *ps, int depth); BOOL srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth); void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs, uint32 hours, uint32 mins, uint32 secs, uint32 hunds, uint32 zone, uint32 tintervals, uint32 day, uint32 month, uint32 year, uint32 weekday); BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth); +BOOL srv_io_q_net_disk_enum(char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps, int depth); +BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth); +BOOL srv_io_q_net_name_validate(char *desc, SRV_Q_NET_NAME_VALIDATE *q_n, prs_struct *ps, int depth); +BOOL srv_io_r_net_name_validate(char *desc, SRV_R_NET_NAME_VALIDATE *r_n, prs_struct *ps, int depth); +BOOL srv_io_q_net_file_query_secdesc(char *desc, SRV_Q_NET_FILE_QUERY_SECDESC *q_n, prs_struct *ps, int depth); +BOOL srv_io_r_net_file_query_secdesc(char *desc, SRV_R_NET_FILE_QUERY_SECDESC *r_n, prs_struct *ps, int depth); +BOOL srv_io_q_net_file_set_secdesc(char *desc, SRV_Q_NET_FILE_SET_SECDESC *q_n, prs_struct *ps, int depth); +BOOL srv_io_r_net_file_set_secdesc(char *desc, SRV_R_NET_FILE_SET_SECDESC *r_n, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_wks.c */ @@ -3516,6 +3659,7 @@ uint32 _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SI uint32 _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u); uint32 _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u); uint32 _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u); +uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u); /*The following definitions come from rpc_server/srv_netlog.c */ @@ -3526,6 +3670,7 @@ BOOL api_netlog_rpc(pipes_struct *p); uint32 _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u); uint32 _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u); uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u); +uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u); uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u); uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u); uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u); @@ -3535,7 +3680,7 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_ BOOL create_next_pdu(pipes_struct *p); BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p); -BOOL setup_fault_pdu(pipes_struct *p); +BOOL setup_fault_pdu(pipes_struct *p, uint32 status); BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, RPC_IFACE* transfer); BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p); @@ -3628,12 +3773,13 @@ BOOL api_spoolss_rpc(pipes_struct *p); /*The following definitions come from rpc_server/srv_spoolss_nt.c */ -void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len); uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u); BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode, NT_DEVICEMODE **pp_nt_devmode); uint32 _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u); uint32 _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u); +uint32 _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, + SPOOL_R_DELETEPRINTERDRIVER *r_u); uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u); uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u); uint32 _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u); @@ -3680,6 +3826,7 @@ BOOL share_info_db_init(void); void map_generic_share_sd_bits(SEC_DESC *psd); BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access); uint32 _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u); +uint32 _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u); uint32 _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u); uint32 _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u); uint32 _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u); @@ -3690,6 +3837,12 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u); uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u); uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u); +uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u, + SRV_R_NET_FILE_QUERY_SECDESC *r_u); +uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u, + SRV_R_NET_FILE_SET_SECDESC *r_u); +uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u); +uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u); /*The following definitions come from rpc_server/srv_util.c */ @@ -3753,6 +3906,7 @@ connection_struct *conn_new(void); void conn_close_all(void); BOOL conn_idle_all(time_t t, int deadtime); void conn_free(connection_struct *conn); +void msg_force_tdis(int msg_type, pid_t pid, void *buf, size_t len); /*The following definitions come from smbd/connection.c */ @@ -3959,11 +4113,12 @@ void generate_next_challenge(char *challenge); BOOL set_challenge(unsigned char *challenge); user_struct *get_valid_user_struct(uint16 vuid); void invalidate_vuid(uint16 vuid); +void invalidate_all_vuids(void); char *validated_username(uint16 vuid); char *validated_domain(uint16 vuid); NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest); -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest); +int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, + char *domain,BOOL guest); void add_session_user(char *user); BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8); BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], @@ -4079,6 +4234,7 @@ int rename_internals(connection_struct *conn, int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize); int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize); int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize); +uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format); SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format); SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err); int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize); @@ -4115,6 +4271,11 @@ int find_service(char *service); connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode); void close_cnum(connection_struct *conn, uint16 vuid); +/*The following definitions come from smbd/session.c */ + +BOOL session_claim(uint16 vuid); +void session_yield(uint16 vuid); + /*The following definitions come from smbd/ssl.c */ int sslutil_init(int isServer); @@ -4158,10 +4319,16 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid); BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype); BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype); +/*The following definitions come from smbd/utmp.c */ + +void sys_utmp_yield(const char *username, const char *hostname, + const char *id_str, int id_num); +void sys_utmp_claim(const char *username, const char *hostname, + const char *id_str, int id_num); + /*The following definitions come from smbd/vfs.c */ -int vfs_init_default(connection_struct *conn); -BOOL vfs_init_custom(connection_struct *conn); +BOOL vfs_init(connection_struct *conn); BOOL vfs_directory_exist(connection_struct *conn, char *dname, SMB_STRUCT_STAT *st); int vfs_mkdir(connection_struct *conn, char *fname, mode_t mode); char *vfs_getwd(connection_struct *conn, char *unix_path); @@ -4208,6 +4375,8 @@ char *vfswrap_getwd(connection_struct *conn, char *path); int vfswrap_utime(connection_struct *conn, char *path, struct utimbuf *times); int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len); BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); +int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath); +int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz); size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc); size_t vfswrap_get_nt_acl(files_struct *fsp, char *name, SEC_DESC **ppdesc); BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd); @@ -4305,7 +4474,9 @@ int tdb_clear_spinlocks(TDB_CONTEXT *tdb); /*The following definitions come from tdb/tdb.c */ +void tdb_dump_all(TDB_CONTEXT *tdb); void tdb_printfreelist(TDB_CONTEXT *tdb); +enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); const char *tdb_errorstr(TDB_CONTEXT *tdb); TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); @@ -4323,6 +4494,7 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]); void tdb_unlockkeys(TDB_CONTEXT *tdb); int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); +void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)); /*The following definitions come from tdb/tdbutil.c */ @@ -4334,8 +4506,11 @@ int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v); int tdb_store_int(TDB_CONTEXT *tdb, char *keystr, int v); int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len); TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr); +int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val); size_t tdb_pack(char *buf, int bufsize, char *fmt, ...); int tdb_unpack(char *buf, int bufsize, char *fmt, ...); +TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode); /*The following definitions come from utils/nbio.c */ diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h index ad7fa31365e..1a6e178068a 100644 --- a/source/include/rpc_lsa.h +++ b/source/include/rpc_lsa.h @@ -48,6 +48,7 @@ enum SID_NAME_USE #define LSA_OPENPOLICY 0x06 #define LSA_OPENPOLICY2 0x2c #define LSA_OPENSECRET 0x1C +#define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */ /* XXXX these are here to get a compile! */ #define LSA_LOOKUPRIDS 0xFD @@ -380,4 +381,31 @@ typedef struct lsa_r_open_secret uint32 status; } LSA_R_OPEN_SECRET; +/* LSA_Q_UNK_GET_CONNUSER - gets username\domain of connected user + called when "Take Ownership" is clicked -SK */ +typedef struct lsa_q_unk_get_connuser +{ + uint32 ptr_srvname; + UNISTR2 uni2_srvname; + uint32 unk1; /* 3 unknown uint32's are seen right after uni2_srvname */ + uint32 unk2; /* unk2 appears to be a ptr, unk1 = unk3 = 0 usually */ + uint32 unk3; +} LSA_Q_UNK_GET_CONNUSER; + +/* LSA_R_UNK_GET_CONNUSER */ +typedef struct lsa_r_unk_get_connuser +{ + uint32 ptr_user_name; + UNIHDR hdr_user_name; + UNISTR2 uni2_user_name; + + uint32 unk1; + + uint32 ptr_dom_name; + UNIHDR hdr_dom_name; + UNISTR2 uni2_dom_name; + + uint32 status; +} LSA_R_UNK_GET_CONNUSER; + #endif /* _RPC_LSA_H */ diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h index 29b17e6a059..f15cec3ca9a 100644 --- a/source/include/rpc_netlogon.h +++ b/source/include/rpc_netlogon.h @@ -26,17 +26,22 @@ /* NETLOGON pipe */ -#define NET_REQCHAL 0x04 -#define NET_SRVPWSET 0x06 #define NET_SAMLOGON 0x02 #define NET_SAMLOGOFF 0x03 +#define NET_REQCHAL 0x04 +#define NET_AUTH 0x05 +#define NET_SRVPWSET 0x06 +#define NET_SAM_DELTAS 0x07 +#define NET_LOGON_CTRL 0x0c #define NET_AUTH2 0x0f #define NET_LOGON_CTRL2 0x0e +#define NET_SAM_SYNC 0x10 #define NET_TRUST_DOM_LIST 0x13 /* Secure Channel types. used in NetrServerAuthenticate negotiation */ #define SEC_CHAN_WKSTA 2 #define SEC_CHAN_DOMAIN 4 +#define SEC_CHAN_BDC 6 #if 0 /* I think this is correct - it's what gets parsed on the wire. JRA. */ @@ -159,25 +164,6 @@ typedef struct net_user_info_3 } NET_USER_INFO_3; -/******************************************************** - Logon Control Query - - query_level 0x1 - pdc status - query_level 0x3 - number of logon attempts. - - ********************************************************/ -/* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2*/ -typedef struct net_q_logon_ctrl2_info -{ - uint32 ptr; /* undocumented buffer pointer */ - UNISTR2 uni_server_name; /* server name, starting with two '\'s */ - - uint32 function_code; /* 0x1 */ - uint32 query_level; /* 0x1, 0x3 */ - uint32 switch_value; /* 0x1 */ - -} NET_Q_LOGON_CTRL2; - /* NETLOGON_INFO_1 - pdc status info, i presume */ typedef struct netlogon_1_info { @@ -210,6 +196,59 @@ typedef struct netlogon_3_info } NETLOGON_INFO_3; +/******************************************************** + Logon Control Query + + This is generated by a nltest /bdc_query:DOMAIN + + query_level 0x1, function_code 0x1 + + ********************************************************/ + +/* NET_Q_LOGON_CTRL - LSA Netr Logon Control */ + +typedef struct net_q_logon_ctrl_info +{ + uint32 ptr; + UNISTR2 uni_server_name; + uint32 function_code; + uint32 query_level; +} NET_Q_LOGON_CTRL; + +/* NET_R_LOGON_CTRL - LSA Netr Logon Control */ + +typedef struct net_r_logon_ctrl_info +{ + uint32 switch_value; + uint32 ptr; + + union { + NETLOGON_INFO_1 info1; + } logon; + + uint32 status; +} NET_R_LOGON_CTRL; + +/******************************************************** + Logon Control2 Query + + query_level 0x1 - pdc status + query_level 0x3 - number of logon attempts. + + ********************************************************/ + +/* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2 */ +typedef struct net_q_logon_ctrl2_info +{ + uint32 ptr; /* undocumented buffer pointer */ + UNISTR2 uni_server_name; /* server name, starting with two '\'s */ + + uint32 function_code; /* 0x1 */ + uint32 query_level; /* 0x1, 0x3 */ + uint32 switch_value; /* 0x1 */ + +} NET_Q_LOGON_CTRL2; + /******************************************************* Logon Control Response @@ -282,7 +321,19 @@ typedef struct net_r_req_chal_info } NET_R_REQ_CHAL; +/* NET_Q_AUTH */ +typedef struct net_q_auth_info +{ + DOM_LOG_INFO clnt_id; /* client identification info */ + DOM_CHAL clnt_chal; /* client-calculated credentials */ +} NET_Q_AUTH; +/* NET_R_AUTH */ +typedef struct net_r_auth_info +{ + DOM_CHAL srv_chal; /* server-calculated credentials */ + uint32 status; /* return code */ +} NET_R_AUTH; /* NET_Q_AUTH_2 */ typedef struct net_q_auth2_info @@ -430,6 +481,4 @@ typedef struct net_r_sam_logoff_info } NET_R_SAM_LOGOFF; - #endif /* _RPC_NETLOGON_H */ - diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h index 15705a1b6cc..cdfb19580de 100644 --- a/source/include/rpc_samr.h +++ b/source/include/rpc_samr.h @@ -219,6 +219,58 @@ typedef struct sam_user_info_24 uint8 pass[516]; } SAM_USER_INFO_24; +/* + * NB. This structure is *definately* incorrect. It's my best guess + * currently for W2K SP2. The password field is encrypted in a different + * way than normal... And there are definately other problems. JRA. + */ + +/* SAM_USER_INFO_25 */ +typedef struct sam_user_info_25 +{ + /* TIMES MAY NOT IN RIGHT ORDER!!!! */ + 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; /* NULL - user name unicode string header */ + UNIHDR hdr_full_name; /* user's full name unicode string header */ + UNIHDR hdr_home_dir; /* home directory unicode string header */ + UNIHDR hdr_dir_drive; /* home drive unicode string header */ + UNIHDR hdr_logon_script; /* logon script unicode string header */ + UNIHDR hdr_profile_path; /* profile path unicode string header */ + UNIHDR hdr_acct_desc ; /* user description */ + UNIHDR hdr_workstations; /* comma-separated workstations user can log in from */ + UNIHDR hdr_unknown_str ; /* don't know what this is, yet. */ + UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */ + + uint8 lm_pwd[16]; /* lm user passwords */ + uint8 nt_pwd[16]; /* nt user passwords */ + + uint32 user_rid; /* Primary User ID */ + uint32 group_rid; /* Primary Group ID */ + + uint32 acb_info; /* account info (ACB_xxxx bit-mask) */ + + uint32 unknown_6[6]; + + uint8 pass[532]; + + UNISTR2 uni_user_name; /* NULL - username unicode string */ + UNISTR2 uni_full_name; /* user's full name unicode string */ + UNISTR2 uni_home_dir; /* home directory unicode string */ + UNISTR2 uni_dir_drive; /* home directory drive unicode string */ + UNISTR2 uni_logon_script; /* logon script unicode string */ + UNISTR2 uni_profile_path; /* profile path unicode string */ + UNISTR2 uni_acct_desc ; /* user description unicode string */ + UNISTR2 uni_workstations; /* login from workstations unicode string */ + UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */ + UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */ +} SAM_USER_INFO_25; + /* SAM_USER_INFO_21 */ typedef struct sam_user_info_21 @@ -565,7 +617,7 @@ typedef struct r_samr_open_domain_info } SAMR_R_OPEN_DOMAIN; -#define MAX_SAM_ENTRIES 250 +#define MAX_SAM_ENTRIES 50 typedef struct samr_entry_info { @@ -734,8 +786,8 @@ typedef struct samr_str_entry_info1 typedef struct sam_entry_info_1 { - SAM_ENTRY1 sam[MAX_SAM_ENTRIES]; - SAM_STR1 str[MAX_SAM_ENTRIES]; + SAM_ENTRY1 *sam; + SAM_STR1 *str; } SAM_DISPINFO_1; @@ -764,8 +816,8 @@ typedef struct samr_str_entry_info2 typedef struct sam_entry_info_2 { - SAM_ENTRY2 sam[MAX_SAM_ENTRIES]; - SAM_STR2 str[MAX_SAM_ENTRIES]; + SAM_ENTRY2 *sam; + SAM_STR2 *str; } SAM_DISPINFO_2; @@ -793,8 +845,8 @@ typedef struct samr_str_entry_info3 typedef struct sam_entry_info_3 { - SAM_ENTRY3 sam[MAX_SAM_ENTRIES]; - SAM_STR3 str[MAX_SAM_ENTRIES]; + SAM_ENTRY3 *sam; + SAM_STR3 *str; } SAM_DISPINFO_3; @@ -816,8 +868,8 @@ typedef struct samr_str_entry_info4 typedef struct sam_entry_info_4 { - SAM_ENTRY4 sam[MAX_SAM_ENTRIES]; - SAM_STR4 str[MAX_SAM_ENTRIES]; + SAM_ENTRY4 *sam; + SAM_STR4 *str; } SAM_DISPINFO_4; @@ -839,8 +891,8 @@ typedef struct samr_str_entry_info5 typedef struct sam_entry_info_5 { - SAM_ENTRY5 sam[MAX_SAM_ENTRIES]; - SAM_STR5 str[MAX_SAM_ENTRIES]; + SAM_ENTRY5 *sam; + SAM_STR5 *str; } SAM_DISPINFO_5; @@ -1140,6 +1192,7 @@ typedef struct sam_userinfo_ctr_info SAM_USER_INFO_21 *id21; /* auth-level 21 */ SAM_USER_INFO_23 *id23; /* auth-level 0x17 */ SAM_USER_INFO_24 *id24; /* auth-level 0x18 */ + SAM_USER_INFO_25 *id25; /* auth-level 0x19 */ void* id; /* to make typecasting easy */ } info; @@ -1249,8 +1302,8 @@ typedef struct q_samr_lookup_names_info uint32 ptr; /* 0x0000 0000 - 32 bit unknown */ uint32 num_names2; /* number of names being looked up */ - UNIHDR hdr_name[MAX_LOOKUP_SIDS]; /* unicode account name header */ - UNISTR2 uni_name[MAX_LOOKUP_SIDS]; /* unicode account name string */ + UNIHDR *hdr_name; /* unicode account name header */ + UNISTR2 *uni_name; /* unicode account name string */ } SAMR_Q_LOOKUP_NAMES; @@ -1530,8 +1583,8 @@ typedef struct q_samr_open_alias_info { POLICY_HND dom_pol; - uint32 unknown_0; /* 0x0000 0008 */ - uint32 rid_alias; /* rid */ + uint32 access_mask; + uint32 rid_alias; } SAMR_Q_OPEN_ALIAS; diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index 1e0a43987cb..dd66982cd5c 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -30,8 +30,6 @@ /* spoolss pipe: this are the calls which are not implemented ... #define SPOOLSS_OPENPRINTER 0x01 #define SPOOLSS_GETPRINTERDRIVER 0x0b -#define SPOOLSS_DELETEPRINTERDRIVER 0x0d -#define SPOOLSS_ADDPRINTPROCESSOR 0x0e #define SPOOLSS_GETPRINTPROCESSORDIRECTORY 0x10 #define SPOOLSS_READPRINTER 0x16 #define SPOOLSS_WAITFORPRINTERCHANGE 0x1c @@ -74,6 +72,8 @@ #define SPOOLSS_ADDPRINTERDRIVER 0x09 #define SPOOLSS_ENUMPRINTERDRIVERS 0x0a #define SPOOLSS_GETPRINTERDRIVERDIRECTORY 0x0c +#define SPOOLSS_DELETEPRINTERDRIVER 0x0d +#define SPOOLSS_ADDPRINTPROCESSOR 0x0e #define SPOOLSS_ENUMPRINTPROCESSORS 0x0f #define SPOOLSS_STARTDOCPRINTER 0x11 #define SPOOLSS_STARTPAGEPRINTER 0x12 @@ -577,6 +577,23 @@ typedef struct spool_r_endpageprinter } SPOOL_R_ENDPAGEPRINTER; + +typedef struct spool_q_deleteprinterdriver +{ + uint32 server_ptr; + UNISTR2 server; + UNISTR2 arch; + UNISTR2 driver; +} +SPOOL_Q_DELETEPRINTERDRIVER; + +typedef struct spool_r_deleteprinterdriver +{ + uint32 status; +} +SPOOL_R_DELETEPRINTERDRIVER; + + typedef struct spool_doc_info_1 { uint32 p_docname; @@ -1558,6 +1575,23 @@ typedef struct spool_r_getprinterdriverdirectory } SPOOL_R_GETPRINTERDRIVERDIR; +typedef struct spool_q_addprintprocessor +{ + uint32 server_ptr; + UNISTR2 server; + UNISTR2 environment; + UNISTR2 path; + UNISTR2 name; +} +SPOOL_Q_ADDPRINTPROCESSOR; + +typedef struct spool_r_addprintprocessor +{ + uint32 status; +} +SPOOL_R_ADDPRINTPROCESSOR; + + typedef struct spool_q_enumprintprocessors { uint32 name_ptr; diff --git a/source/include/rpc_srvsvc.h b/source/include/rpc_srvsvc.h index 2224f387662..d6fe7617b25 100644 --- a/source/include/rpc_srvsvc.h +++ b/source/include/rpc_srvsvc.h @@ -36,8 +36,48 @@ #define SRV_NET_SHARE_DEL 0x12 #define SRV_NET_SRV_GET_INFO 0x15 #define SRV_NET_SRV_SET_INFO 0x16 +#define SRV_NET_DISK_ENUM 0x17 #define SRV_NET_REMOTE_TOD 0x1c +#define SRV_NET_NAME_VALIDATE 0x21 #define SRV_NETSHAREENUM 0x24 +#define SRV_NETFILEQUERYSECDESC 0x27 +#define SRV_NETFILESETSECDESC 0x28 + +#define MAX_SERVER_DISK_ENTRIES 15 + +typedef struct disk_info { + uint32 unknown; + UNISTR3 disk_name; +} DISK_INFO; + +typedef struct disk_enum_container { + uint32 level; + uint32 entries_read; + uint32 unknown; + uint32 disk_info_ptr; + DISK_INFO disk_info[MAX_SERVER_DISK_ENTRIES]; +} DISK_ENUM_CONTAINER; + +typedef struct net_srv_disk_enum { + uint32 ptr_srv_name; /* pointer (to server name?) */ + UNISTR2 uni_srv_name; /* server name */ + + DISK_ENUM_CONTAINER disk_enum_ctr; + + uint32 preferred_len; /* preferred maximum length (0xffff ffff) */ + uint32 total_entries; /* total number of entries */ + ENUM_HND enum_hnd; + uint32 status; /* return status */ +} SRV_Q_NET_DISK_ENUM, SRV_R_NET_DISK_ENUM; + +typedef struct net_name_validate { + uint32 ptr_srv_name; + UNISTR2 uni_srv_name; + UNISTR2 uni_name; /*name to validate*/ + uint32 type; + uint32 flags; + uint32 status; +} SRV_Q_NET_NAME_VALIDATE, SRV_R_NET_NAME_VALIDATE; /* SESS_INFO_0 (pointers to level 0 session info strings) */ typedef struct ptr_sess_info0 @@ -328,6 +368,8 @@ typedef struct ptr_share_info502 /* SH_INFO_502_STR (level 502 share info strings) */ typedef struct str_share_info502 { + SH_INFO_502 *ptrs; + UNISTR2 uni_netname; /* unicode string of net name (e.g NETLOGON) */ UNISTR2 uni_remark; /* unicode string of comment (e.g "Logon server share") */ UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */ @@ -723,5 +765,48 @@ typedef struct r_net_remote_tod } SRV_R_NET_REMOTE_TOD; +/* SRV_Q_NET_FILE_QUERY_SECDESC */ +typedef struct q_net_file_query_secdesc +{ + uint32 ptr_srv_name; + UNISTR2 uni_srv_name; + uint32 ptr_qual_name; + UNISTR2 uni_qual_name; + UNISTR2 uni_file_name; + uint32 unknown1; + uint32 unknown2; + uint32 unknown3; +} SRV_Q_NET_FILE_QUERY_SECDESC; + +/* SRV_R_NET_FILE_QUERY_SECDESC */ +typedef struct r_net_file_query_secdesc +{ + uint32 ptr_response; + uint32 size_response; + uint32 ptr_secdesc; + uint32 size_secdesc; + SEC_DESC *sec_desc; + uint32 status; +} SRV_R_NET_FILE_QUERY_SECDESC; +/* SRV_Q_NET_FILE_SET_SECDESC */ +typedef struct q_net_file_set_secdesc +{ + uint32 ptr_srv_name; + UNISTR2 uni_srv_name; + uint32 ptr_qual_name; + UNISTR2 uni_qual_name; + UNISTR2 uni_file_name; + uint32 sec_info; + uint32 size_set; + uint32 ptr_secdesc; + uint32 size_secdesc; + SEC_DESC *sec_desc; +} SRV_Q_NET_FILE_SET_SECDESC; + +/* SRV_R_NET_FILE_SET_SECDESC */ +typedef struct r_net_file_set_secdesc +{ + uint32 status; +} SRV_R_NET_FILE_SET_SECDESC; #endif /* _RPC_SRVSVC_H */ diff --git a/source/include/safe_string.h b/source/include/safe_string.h index 815939d1541..2c3d2eda01f 100644 --- a/source/include/safe_string.h +++ b/source/include/safe_string.h @@ -37,11 +37,6 @@ #endif /* sprintf */ #define sprintf __ERROR__XX__NEVER_USE_SPRINTF__; -#ifdef snprintf -#undef snprintf -#endif /* snprintf */ -#define snprintf __ERROR__XX__NEVER_USE_SNPRINTF___; - #define pstrcpy(d,s) safe_strcpy((d),(s),sizeof(pstring)-1) #define pstrcat(d,s) safe_strcat((d),(s),sizeof(pstring)-1) #define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1) diff --git a/source/include/smb.h b/source/include/smb.h index d8bd852b859..7cb9c0bb973 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -27,6 +27,7 @@ #define BUFFER_SIZE (0xFFFF) #define SAFETY_MARGIN 1024 +#define LARGE_WRITEX_HDR_SIZE 65 #define NMB_PORT 137 #define DGRAM_PORT 138 @@ -56,7 +57,7 @@ typedef int BOOL; #define STR_UPPER 4 #define STR_ASCII 8 #define STR_UNICODE 16 - +#define STR_NOALIGN 32 /* how long to wait for secondary SMB packets (milli-seconds) */ #define SMB_SECONDARY_WAIT (60*1000) @@ -176,6 +177,7 @@ implemented */ #define ERRfilexists 80 /* File in operation already exists */ #define ERRcannotopen 110 /* Cannot open the file specified */ #define ERRunknownlevel 124 +#define ERRnotlocked 158 /* This region is not locked by this locking context. */ #define ERRrename 183 #define ERRbadpipe 230 /* Named pipe invalid */ #define ERRpipebusy 231 /* All instances of pipe are busy */ @@ -205,6 +207,7 @@ implemented */ #define ERROR_INVALID_PRINTER_NAME (1801) #define ERROR_INVALID_DATATYPE (1804) #define ERROR_INVALID_ENVIRONMENT (1805) +#define ERROR_PRINTER_DRIVER_IN_USE (3001) /* here's a special one from observing NT */ #define ERRnoipc 66 /* don't support ipc */ @@ -1178,6 +1181,16 @@ struct bitmap { FILE_EXECUTE|SYNCHRONIZE_ACCESS) /* Mapping of access rights to UNIX perms. */ +#define UNIX_ACCESS_RWX FILE_GENERIC_ALL +#define UNIX_ACCESS_R FILE_GENERIC_READ +#define UNIX_ACCESS_W FILE_GENERIC_WRITE +#define UNIX_ACCESS_X FILE_GENERIC_EXECUTE + +#if 0 +/* + * This is the old mapping we used to use. To get W2KSP2 profiles + * working we need to map to the canonical file perms. + */ #define UNIX_ACCESS_RWX (UNIX_ACCESS_R|UNIX_ACCESS_W|UNIX_ACCESS_X) #define UNIX_ACCESS_R (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\ FILE_READ_ATTRIBUTES|FILE_READ_EA|FILE_READ_DATA) @@ -1186,6 +1199,7 @@ struct bitmap { FILE_APPEND_DATA|FILE_WRITE_DATA) #define UNIX_ACCESS_X (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\ FILE_EXECUTE|FILE_READ_ATTRIBUTES) +#endif #define UNIX_ACCESS_NONE (WRITE_OWNER_ACCESS) @@ -1404,7 +1418,9 @@ char *strdup(char *s); #define CAP_LOCK_AND_READ 0x0100 #define CAP_NT_FIND 0x0200 #define CAP_DFS 0x1000 +#define CAP_W2K_SMBS 0x2000 #define CAP_LARGE_READX 0x4000 +#define CAP_LARGE_WRITEX 0x8000 #define CAP_EXTENDED_SECURITY 0x80000000 /* protocol types. It assumes that higher protocols include lower protocols @@ -1700,6 +1716,8 @@ typedef struct user_struct gid_t *groups; NT_USER_TOKEN *nt_user_token; + + int session_id; /* used by utmp and pam session code */ } user_struct; #include "ntdomain.h" diff --git a/source/include/smb_acls.h b/source/include/smb_acls.h index 613f6db3e32..bea90bf46a0 100644 --- a/source/include/smb_acls.h +++ b/source/include/smb_acls.h @@ -124,48 +124,6 @@ typedef struct SMB_ACL_T { #define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS #define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT -/* XFS ACLS are defined here */ -/* donated by John Trostel (jtrostel@connex.com) */ - -#elif defined(HAVE_XFS_ACLS) - -/* This is an nearly an identity mapping (just remove the SMB_). */ -#define SMB_ACL_TAG_T acl_tag_t -#define SMB_ACL_TYPE_T acl_type_t -//#define SMB_ACL_PERMSET_T acl_permset_t -typedef ushort *SMB_ACL_PERMSET_T; -#define SMB_ACL_PERM_T acl_perm_t -#define SMB_ACL_READ ACL_READ -#define SMB_ACL_WRITE ACL_WRITE -#define SMB_ACL_EXECUTE ACL_EXECUTE - -/* Types of ACLs. */ -#define SMB_ACL_USER ACL_USER -#define SMB_ACL_USER_OBJ ACL_USER_OBJ -#define SMB_ACL_GROUP ACL_GROUP -#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ -#define SMB_ACL_OTHER ACL_OTHER_OBJ -#define SMB_ACL_MASK ACL_MASK - -#define SMB_ACL_T acl_t - -#define SMB_ACL_ENTRY_T acl_entry_t - -#define SMB_ACL_FIRST_ENTRY ACL_FIRST_ENTRY -#define SMB_ACL_NEXT_ENTRY ACL_NEXT_ENTRY - -#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS -#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT - -/* Not yet in Official SGI XFS CVS */ - -#if defined(CONFIG_EXTENDED_PERMISSSION) -#define SMB_ACL_CHOWN ACL_CHOWN -#define SMB_ACL_CHMOD ACL_CHMOD -#define SMB_ACL_DELETE ACL_DELETE -#define EXTENDED_PERM_BITS (ACL_CHOWN|ACL_CHMOD|ACL_DELETE) -#endif /* CONFIG_EXTENDED_PERMISSION */ - #elif defined(HAVE_AIX_ACLS) /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */ diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h index 2e74d7e69f5..cad6229f1ae 100644 --- a/source/include/smb_macros.h +++ b/source/include/smb_macros.h @@ -128,6 +128,7 @@ #define SMB_LPID_OFFSET(indx) (10 * (indx)) #define SMB_LKOFF_OFFSET(indx) ( 2 + (10 * (indx))) #define SMB_LKLEN_OFFSET(indx) ( 6 + (10 * (indx))) +#define SMB_LARGE__LPID_OFFSET(indx) (20 * (indx)) #define SMB_LARGE_LKOFF_OFFSET_HIGH(indx) (4 + (20 * (indx))) #define SMB_LARGE_LKOFF_OFFSET_LOW(indx) (8 + (20 * (indx))) #define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx))) diff --git a/source/include/talloc.h b/source/include/talloc.h index 32b0f28ae6d..89c2f82e056 100644 --- a/source/include/talloc.h +++ b/source/include/talloc.h @@ -21,17 +21,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef DEBUG_TALLOC -#define BAD_PTR (void*)0xdeadbeef -#else -#define BAD_PTR NULL -#endif - struct talloc_chunk { struct talloc_chunk *next; + size_t size; void *ptr; - size_t alloc_size; - size_t total_size; }; typedef struct { diff --git a/source/include/version.h b/source/include/version.h index 14d0827c298..682efc644da 100644 --- a/source/include/version.h +++ b/source/include/version.h @@ -1 +1 @@ -#define VERSION "2.2.0a" +#define VERSION "2.2.1" diff --git a/source/include/vfs.h b/source/include/vfs.h index 51f3df1ec95..93823a5f239 100644 --- a/source/include/vfs.h +++ b/source/include/vfs.h @@ -86,6 +86,8 @@ struct vfs_ops { int (*utime)(struct connection_struct *conn, char *path, struct utimbuf *times); int (*ftruncate)(struct files_struct *fsp, int fd, SMB_OFF_T offset); BOOL (*lock)(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); + int (*symlink)(struct connection_struct *conn, const char *oldpath, const char *newpath); + int (*readlink)(struct connection_struct *conn, const char *path, char *buf, size_t bufsiz); /* NT ACL operations. */ diff --git a/source/lib/access.c b/source/lib/access.c index bcfef1dc2ff..ed4d5ac3631 100644 --- a/source/lib/access.c +++ b/source/lib/access.c @@ -260,13 +260,12 @@ static BOOL only_ipaddrs_in_list(const char* list) if (!is_ipaddress(tok)) { - char *p; /* * if we failed, make sure that it was not because the token * was a network/netmask pair. Only network/netmask pairs * have a '/' in them */ - if ((p=strchr(tok, '/')) == NULL) + if (strchr(tok, '/') == NULL) { only_ip = False; DEBUG(3,("only_ipaddrs_in_list: list [%s] has non-ip address %s\n", list, tok)); diff --git a/source/lib/debug.c b/source/lib/debug.c index 9c97385db33..4ec70bd118a 100644 --- a/source/lib/debug.c +++ b/source/lib/debug.c @@ -180,7 +180,7 @@ BOOL debug_parse_params(char **params, int *debuglevel_class) /* Allow DBGC_ALL to be specifies w/o requiring its class name e.g."10" * v.s. "all:10", this is the traditional way to set DEBUGLEVEL */ - if (isdigit(params[0][0])) { + if (isdigit((int)params[0][0])) { debuglevel_class[DBGC_ALL] = atoi(params[0]); i = 1; /* start processing at the next params */ } @@ -242,9 +242,9 @@ void debug_message(int msg_type, pid_t src, void *buf, size_t len) /* Set the new DEBUGLEVEL_CLASS array from the pased array */ memcpy(DEBUGLEVEL_CLASS, buf, sizeof(DEBUGLEVEL_CLASS)); - DEBUG(1,("INFO: Debug class %s level = %d (pid %d from pid %d)\n", + DEBUG(1,("INFO: Debug class %s level = %d (pid %u from pid %u)\n", classname_table[DBGC_ALL], - DEBUGLEVEL_CLASS[DBGC_ALL], getpid(), (int)src)); + DEBUGLEVEL_CLASS[DBGC_ALL], (unsigned int)getpid(), (unsigned int)src)); for (i=1; i<DBGC_LAST; i++) { if (DEBUGLEVEL_CLASS[i]) @@ -310,21 +310,14 @@ BOOL reopen_logs( void ) FILE *new_dbf = NULL; BOOL ret = True; - if (DEBUGLEVEL_CLASS[ DBGC_ALL ] <= 0) { - if (dbf) { - (void)fclose(dbf); - dbf = NULL; - } - return True; - } - oldumask = umask( 022 ); pstrcpy(fname, debugf ); if (lp_loaded() && (*lp_logfile())) pstrcpy(fname, lp_logfile()); - pstrcpy( debugf, fname ); + pstrcpy(debugf, fname); + if (append_log) new_dbf = sys_fopen( debugf, "a" ); else @@ -450,26 +443,14 @@ void check_log_size( void ) * This is called by dbghdr() and format_debug_text(). * ************************************************************************** ** */ -#ifdef HAVE_STDARG_H int Debug1( char *format_str, ... ) { -#else - int Debug1(va_alist) -va_dcl -{ - char *format_str; -#endif va_list ap; int old_errno = errno; if( stdout_logging ) { -#ifdef HAVE_STDARG_H va_start( ap, format_str ); -#else - va_start( ap ); - format_str = va_arg( ap, char * ); -#endif if(dbf) (void)vfprintf( dbf, format_str, ap ); va_end( ap ); @@ -524,12 +505,7 @@ va_dcl else priority = priority_map[syslog_level]; -#ifdef HAVE_STDARG_H va_start( ap, format_str ); -#else - va_start( ap ); - format_str = va_arg( ap, char * ); -#endif vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap ); va_end( ap ); @@ -544,12 +520,7 @@ va_dcl if( !lp_syslog_only() ) #endif { -#ifdef HAVE_STDARG_H va_start( ap, format_str ); -#else - va_start( ap ); - format_str = va_arg( ap, char * ); -#endif if(dbf) (void)vfprintf( dbf, format_str, ap ); va_end( ap ); @@ -740,7 +711,6 @@ BOOL dbghdr( int level, char *file, char *func, int line ) * * ************************************************************************** ** */ -#ifdef HAVE_STDARG_H BOOL dbgtext( char *format_str, ... ) { va_list ap; @@ -755,24 +725,5 @@ BOOL dbghdr( int level, char *file, char *func, int line ) return( True ); } /* dbgtext */ -#else - BOOL dbgtext( va_alist ) - va_dcl - { - char *format_str; - va_list ap; - pstring msgbuf; - - va_start( ap ); - format_str = va_arg( ap, char * ); - vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap ); - va_end( ap ); - - format_debug_text( msgbuf ); - - return( True ); - } /* dbgtext */ - -#endif /* ************************************************************************** */ diff --git a/source/lib/genrand.c b/source/lib/genrand.c index 4a7de802e8f..7af44118ae5 100644 --- a/source/lib/genrand.c +++ b/source/lib/genrand.c @@ -1,10 +1,10 @@ /* Unix SMB/Netbios implementation. - Version 1.9. + Version 2.2 Functions to create reasonable random numbers for crypto use. - Copyright (C) Jeremy Allison 1998 + Copyright (C) Jeremy Allison 2001 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 @@ -24,208 +24,230 @@ #include "includes.h" extern int DEBUGLEVEL; -static uint32 counter = 0; + + +static unsigned char hash[258]; +static uint32 counter; +unsigned char *reseed_data; +size_t reseed_data_size; + +/**************************************************************** + Copy any user given reseed data. +*****************************************************************/ + +void set_rand_reseed_data(unsigned char *data, size_t len) +{ + if (reseed_data) + free(reseed_data); + reseed_data_size = 0; + + reseed_data = (unsigned char *)memdup(data, len); + if (reseed_data) + reseed_data_size = len; +} + +/**************************************************************** + Setup the seed. +*****************************************************************/ + +static void seed_random_stream(unsigned char *seedval, size_t seedlen) +{ + unsigned char j = 0; + size_t ind; + + for (ind = 0; ind < 256; ind++) + hash[ind] = (unsigned char)ind; + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (hash[ind] + seedval[ind%seedlen]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + hash[256] = 0; + hash[257] = 0; +} + +/**************************************************************** + Get datasize bytes worth of random data. +*****************************************************************/ + +static void get_random_stream(unsigned char *data, size_t datasize) +{ + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + size_t ind; + + for( ind = 0; ind < datasize; ind++) { + unsigned char tc; + unsigned char 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]; + } + + hash[256] = index_i; + hash[257] = index_j; +} /**************************************************************** -get a 16 byte hash from the contents of a file -Note that the hash is not initialised. + Get a 16 byte hash from the contents of a file. + Note that the hash is not initialised. *****************************************************************/ -static void do_filehash(char *fname, unsigned char *hash) + +static void do_filehash(char *fname, unsigned char *the_hash) { unsigned char buf[1011]; /* deliberate weird size */ unsigned char tmp_md4[16]; int fd, n; fd = sys_open(fname,O_RDONLY,0); - if (fd == -1) return; + if (fd == -1) + return; while ((n = read(fd, (char *)buf, sizeof(buf))) > 0) { mdfour(tmp_md4, buf, n); for (n=0;n<16;n++) - hash[n] ^= tmp_md4[n]; + the_hash[n] ^= tmp_md4[n]; } close(fd); } - - -/**************************************************************** - Try and get a seed by looking at the atimes of files in a given - directory. XOR them into the buf array. -*****************************************************************/ - -static void do_dirrand(char *name, unsigned char *buf, int buf_len) -{ - DIR *dp = opendir(name); - pstring fullname; - int len_left; - int fullname_len; - char *pos; - - pstrcpy(fullname, name); - fullname_len = strlen(fullname); - - if(fullname_len + 2 > sizeof(pstring)) - return; - - if(fullname[fullname_len] != '/') { - fullname[fullname_len] = '/'; - fullname[fullname_len+1] = '\0'; - fullname_len = strlen(fullname); - } - - len_left = sizeof(pstring) - fullname_len - 1; - pos = &fullname[fullname_len]; - - if(dp != NULL) { - char *p; - - while ((p = readdirname(dp))) { - SMB_STRUCT_STAT st; - - if(strlen(p) <= len_left) - pstrcpy(pos, p); - - if(sys_stat(fullname,&st) == 0) { - SIVAL(buf, ((counter * 4)%(buf_len-4)), - IVAL(buf,((counter * 4)%(buf_len-4))) ^ st.st_atime); - counter++; - DEBUG(10,("do_dirrand: value from file %s.\n", fullname)); - } - } - closedir(dp); - } -} - /************************************************************** Try and get a good random number seed. Try a number of - different factors. Firstly, try /dev/urandom and try and - read from this. If this fails iterate through /tmp and - /dev and XOR all the file timestamps. Next add in - a hash of the contents of /etc/shadow and the smb passwd - file and a combination of pid and time of day (yes I know this - sucks :-). Finally md4 the result. + different factors. Firstly, try /dev/urandom - use if exists. We use /dev/urandom as a read of /dev/random can block if the entropy pool dries up. This leads clients to timeout or be very slow on connect. - The result goes in a 16 byte buffer passed from the caller + If we can't use /dev/urandom then seed the stream random generator + above... **************************************************************/ -static uint32 do_reseed(unsigned char *md4_outbuf) +static int do_reseed(BOOL use_fd, int fd) { - unsigned char md4_inbuf[40]; - BOOL got_random = False; - uint32 v1, v2, ret; - int fd; - struct timeval tval; - pid_t mypid; - struct passwd *pw; - - memset(md4_inbuf, '\0', sizeof(md4_inbuf)); - - fd = sys_open( "/dev/urandom", O_RDONLY,0); - if(fd >= 0) { - /* - * We can use /dev/urandom ! - */ - if(read(fd, md4_inbuf, 40) == 40) { - got_random = True; - DEBUG(10,("do_reseed: got 40 bytes from /dev/urandom.\n")); - } - close(fd); - } - - if(!got_random) { - /* - * /dev/urandom failed - try /dev for timestamps. - */ - do_dirrand("/dev", md4_inbuf, sizeof(md4_inbuf)); - } - - /* possibly add in some secret file contents */ - do_filehash("/etc/shadow", &md4_inbuf[0]); - do_filehash(lp_smb_passwd_file(), &md4_inbuf[16]); - - /* add in the root encrypted password. On any system where security is taken - seriously this will be secret */ - pw = sys_getpwnam("root"); - if (pw && pw->pw_passwd) { - int i; - unsigned char md4_tmp[16]; - mdfour(md4_tmp, (unsigned char *)pw->pw_passwd, strlen(pw->pw_passwd)); - for (i=0;i<16;i++) - md4_inbuf[8+i] ^= md4_tmp[i]; - } - - /* - * Finally add the counter, time of day, and pid. - */ - GetTimeOfDay(&tval); - mypid = sys_getpid(); - v1 = (counter++) + mypid + tval.tv_sec; - v2 = (counter++) * mypid + tval.tv_usec; - - SIVAL(md4_inbuf, 32, v1 ^ IVAL(md4_inbuf, 32)); - SIVAL(md4_inbuf, 36, v2 ^ IVAL(md4_inbuf, 36)); - - mdfour(md4_outbuf, md4_inbuf, sizeof(md4_inbuf)); - - /* - * Return a 32 bit int created from XORing the - * 16 bit return buffer. - */ - - ret = IVAL(md4_outbuf, 0); - ret ^= IVAL(md4_outbuf, 4); - ret ^= IVAL(md4_outbuf, 8); - return (ret ^ IVAL(md4_outbuf, 12)); + unsigned char seed_inbuf[40]; + uint32 v1, v2; struct timeval tval; pid_t mypid; + struct passwd *pw; + + if (use_fd) { + if (fd != -1) + return fd; + + fd = sys_open( "/dev/urandom", O_RDONLY,0); + if(fd >= 0) + return fd; + } + +#ifdef __INSURE__ + memset(seed_inbuf, '\0', sizeof(seed_inbuf)); +#endif + + /* Add in some secret file contents */ + + do_filehash("/etc/shadow", &seed_inbuf[0]); + do_filehash(lp_smb_passwd_file(), &seed_inbuf[16]); + + /* + * Add in the root encrypted password. + * On any system where security is taken + * seriously this will be secret. + */ + + pw = sys_getpwnam("root"); + if (pw && pw->pw_passwd) { + size_t i; + unsigned char md4_tmp[16]; + mdfour(md4_tmp, (unsigned char *)pw->pw_passwd, strlen(pw->pw_passwd)); + for (i=0;i<16;i++) + seed_inbuf[8+i] ^= md4_tmp[i]; + } + + /* + * Add the counter, time of day, and pid. + */ + + GetTimeOfDay(&tval); + mypid = sys_getpid(); + v1 = (counter++) + mypid + tval.tv_sec; + v2 = (counter++) * mypid + tval.tv_usec; + + SIVAL(seed_inbuf, 32, v1 ^ IVAL(seed_inbuf, 32)); + SIVAL(seed_inbuf, 36, v2 ^ IVAL(seed_inbuf, 36)); + + /* + * Add any user-given reseed data. + */ + + if (reseed_data) { + size_t i; + for (i = 0; i < sizeof(seed_inbuf); i++) + seed_inbuf[i] ^= reseed_data[i % reseed_data_size]; + } + + seed_random_stream(seed_inbuf, sizeof(seed_inbuf)); + + return -1; } /******************************************************************* Interface to the (hopefully) good crypto random number generator. ********************************************************************/ -void generate_random_buffer( unsigned char *out, int len, BOOL re_seed) +void generate_random_buffer( unsigned char *out, int len, BOOL do_reseed_now) { - static BOOL done_reseed = False; - static unsigned char md4_buf[16]; - unsigned char tmp_buf[16]; - unsigned char *p; - - if(!done_reseed || re_seed) { - sys_srandom(do_reseed(md4_buf)); - done_reseed = True; - } - - /* - * Generate random numbers in chunks of 64 bytes, - * then md4 them & copy to the output buffer. - * Added XOR with output from random, seeded - * by the original md4_buf. This is to stop the - * output from this function being the previous - * md4_buf md4'ed. The output from this function - * is often output onto the wire, and so it should - * not be possible to guess the next output from - * this function based on the previous output. - * XORing in the output from random(), seeded by - * the original md4 hash should stop this. JRA. - */ - - p = out; - while(len > 0) { - int i; - int copy_len = len > 16 ? 16 : len; - mdfour(tmp_buf, md4_buf, sizeof(md4_buf)); - memcpy(md4_buf, tmp_buf, sizeof(md4_buf)); - /* XOR in output from random(). */ - for(i = 0; i < 4; i++) - SIVAL(tmp_buf, i*4, (IVAL(tmp_buf, i*4) ^ (uint32)sys_random())); - memcpy(p, tmp_buf, copy_len); - p += copy_len; - len -= copy_len; - } + static BOOL done_reseed = False; + static int urand_fd = -1; + unsigned char md4_buf[64]; + unsigned char tmp_buf[16]; + unsigned char *p; + + if(!done_reseed || do_reseed_now) { + urand_fd = do_reseed(True, urand_fd); + done_reseed = True; + } + + if (urand_fd != -1 && len > 0) { + + if (read(urand_fd, out, len) == len) + return; /* len bytes of random data read from urandom. */ + + /* Read of urand error, drop back to non urand method. */ + close(urand_fd); + urand_fd = -1; + do_reseed(False, -1); + done_reseed = True; + } + + /* + * Generate random numbers in chunks of 64 bytes, + * then md4 them & copy to the output buffer. + * This way the raw state of the stream is never externally + * seen. + */ + + p = out; + while(len > 0) { + int copy_len = len > 16 ? 16 : len; + + get_random_stream(md4_buf, sizeof(md4_buf)); + mdfour(tmp_buf, md4_buf, sizeof(md4_buf)); + memcpy(p, tmp_buf, copy_len); + p += copy_len; + len -= copy_len; + } } /******************************************************************* diff --git a/source/lib/hash.c b/source/lib/hash.c index c96315f37e0..92840a4c983 100644 --- a/source/lib/hash.c +++ b/source/lib/hash.c @@ -92,7 +92,7 @@ BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compar ************************************************************** */ -int string_hash(int hash_size, const char *key) +static int string_hash(int hash_size, const char *key) { int j=0; while (*key) @@ -147,7 +147,7 @@ static hash_element *hash_chain_find(hash_table *table, ubi_dlList *hash_chain, hash_element *hash_lookup(hash_table *table, char *key) { - return (hash_chain_find(table, &(table->buckets[string_hash(table->size, key)]), key)); + return (hash_chain_find(table, &table->buckets[string_hash(table->size, key)], key)); } /* *************************************************************** @@ -198,7 +198,7 @@ hash_element *hash_insert(hash_table *table, char *value, char *key) table->num_elements += 1; } - bucket = &(table->buckets[string_hash(table->size, key)]); + bucket = &table->buckets[string_hash(table->size, key)]; /* Since we only have 1-byte for the key string, we need to * allocate extra space in the hash_element to store the entire key @@ -301,7 +301,7 @@ static BOOL enlarge_hash_table(hash_table *table) ************************************************************************* */ -BOOL hash_clear(hash_table *table) +void hash_clear(hash_table *table) { int i; ubi_dlList *bucket = table->buckets; @@ -319,6 +319,4 @@ BOOL hash_clear(hash_table *table) if(table->buckets) free((char *) table->buckets); table->buckets = NULL; - - return True; } diff --git a/source/lib/messages.c b/source/lib/messages.c index 5591f141cc1..ffa873960e7 100644 --- a/source/lib/messages.c +++ b/source/lib/messages.c @@ -70,7 +70,7 @@ a useful function for testing the message system ****************************************************************************/ void ping_message(int msg_type, pid_t src, void *buf, size_t len) { - DEBUG(1,("INFO: Received PING message from PID %d\n",src)); + DEBUG(1,("INFO: Received PING message from PID %u\n",(unsigned int)src)); message_send_pid(src, MSG_PONG, buf, len, True); } /**************************************************************************** @@ -78,7 +78,7 @@ return current debug level ****************************************************************************/ void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len) { - DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %d\n",src)); + DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src)); message_send_pid(src, MSG_DEBUGLEVEL, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS), True); } @@ -89,7 +89,7 @@ BOOL message_init(void) { if (tdb) return True; - tdb = tdb_open(lock_path("messages.tdb"), + tdb = tdb_open_log(lock_path("messages.tdb"), 0, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT,0600); @@ -361,9 +361,13 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void struct connections_data crec; struct msg_all *msg_all = (struct msg_all *)state; + if (dbuf.dsize != sizeof(crec)) + return 0; + memcpy(&crec, dbuf.dptr, sizeof(crec)); - if (crec.cnum != -1) return 0; + if (crec.cnum != -1) + return 0; /* if the msg send fails because the pid was not found (i.e. smbd died), * the msg has already been deleted from the messages.tdb.*/ @@ -372,8 +376,8 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void /* if the pid was not found delete the entry from connections.tdb */ if (errno == ESRCH) { - DEBUG(2,("pid %d doesn't exist - deleting connections %d [%s]\n", - crec.pid, crec.cnum, crec.name)); + DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n", + (unsigned int)crec.pid, crec.cnum, crec.name)); tdb_delete(the_tdb, kbuf); } } diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c index b4591c7dbc4..87e40049e05 100644 --- a/source/lib/ms_fnmatch.c +++ b/source/lib/ms_fnmatch.c @@ -24,22 +24,15 @@ */ -#if FNMATCH_TEST -#include <stdio.h> -#include <stdlib.h> -#else #include "includes.h" -#endif - - /* bugger. we need a separate wildcard routine for older versions of the protocol. This is not yet perfect, but its a lot better thaan what we had */ -static int ms_fnmatch_lanman_core(char *pattern, char *string) +static int ms_fnmatch_lanman_core(const char *pattern, const char *string) { - char *p = pattern, *n = string; + const char *p = pattern, *n = string; char c; if (strcmp(p,"?")==0 && strcmp(n,".")==0) goto match; @@ -118,7 +111,7 @@ next: return 0; } -static int ms_fnmatch_lanman1(char *pattern, char *string) +static int ms_fnmatch_lanman1(const char *pattern, const char *string) { if (!strpbrk(pattern, "?*<>\"")) { if (strcmp(string,"..") == 0) string = "."; @@ -142,9 +135,9 @@ static int ms_fnmatch_lanman1(char *pattern, char *string) Returns 0 on match, -1 on fail. */ -int ms_fnmatch(char *pattern, char *string) +int ms_fnmatch(const char *pattern, const char *string) { - char *p = pattern, *n = string; + const char *p = pattern, *n = string; char c; extern int Protocol; @@ -201,59 +194,3 @@ int ms_fnmatch(char *pattern, char *string) return -1; } - - -#if FNMATCH_TEST - -static int match_one(char *pattern, char *file) -{ - if (strcmp(file,"..") == 0) file = "."; - if (strcmp(pattern,".") == 0) return -1; - - return ms_fnmatch(pattern, file); -} - -static char *match_test(char *pattern, char *file, char *short_name) -{ - static char ret[4]; - strncpy(ret, "---", 3); - - if (match_one(pattern, ".") == 0) ret[0] = '+'; - if (match_one(pattern, "..") == 0) ret[1] = '+'; - if (match_one(pattern, file) == 0 || - (*short_name && match_one(pattern, short_name)==0)) ret[2] = '+'; - return ret; -} - - int main(int argc, char *argv[]) -{ - int ret; - char ans[4], mask[100], file[100], mfile[100]; - char *ans2; - int n, i=0; - char line[200]; - - if (argc == 3) { - ret = ms_fnmatch(argv[1], argv[2]); - if (ret == 0) - printf("YES\n"); - else printf("NO\n"); - return ret; - } - mfile[0] = 0; - - while (fgets(line, sizeof(line)-1, stdin)) { - n = sscanf(line, "%3s %s %s %s\n", ans, mask, file, mfile); - if (n < 3) continue; - ans2 = match_test(mask, file, mfile); - if (strcmp(ans2, ans)) { - printf("%s %s %d mask=[%s] file=[%s] mfile=[%s]\n", - ans, ans2, i, mask, file, mfile); - } - i++; - mfile[0] = 0; - } - return 0; -} -#endif /* FNMATCH_TEST */ - diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c index 1a8c10afc40..0a52e1762b1 100644 --- a/source/lib/snprintf.c +++ b/source/lib/snprintf.c @@ -49,41 +49,38 @@ * fixed handling of %.0f * added test for HAVE_LONG_DOUBLE * + * tridge@samba.org, idra@samba.org, April 2001 + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * **************************************************************/ +#ifndef NO_CONFIG_H /* for some tests */ #include "config.h" +#endif +#ifdef HAVE_STRING_H #include <string.h> -# include <ctype.h> -#include <sys/types.h> - -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) - -/* Define this as a fall through, HAVE_STDARG_H is probably already set */ - -#define HAVE_VARARGS_H +#endif -/* varargs declarations: */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#ifdef HAVE_CTYPE_H +#include <ctype.h> +#endif +#include <sys/types.h> +#include <stdarg.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif -#if defined(HAVE_STDARG_H) -# include <stdarg.h> -# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ -# define VA_LOCAL_DECL va_list ap -# define VA_START(f) va_start(ap, f) -# define VA_SHIFT(v,t) ; /* no-op for ANSI */ -# define VA_END va_end(ap) +#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) +/* only include stdio.h if we are not re-defining snprintf or vsnprintf */ +#include <stdio.h> + /* make the compiler happy with an empty file */ + void dummy_snprintf(void) {} #else -# if defined(HAVE_VARARGS_H) -# include <varargs.h> -# undef HAVE_STDARGS -# define VA_LOCAL_DECL va_list ap -# define VA_START(f) va_start(ap) /* f is ignored! */ -# define VA_SHIFT(v,t) v = va_arg(ap,t) -# define VA_END va_end(ap) -# else -/*XX ** NO VARARGS ** XX*/ -# endif -#endif #ifdef HAVE_LONG_DOUBLE #define LDOUBLE long double @@ -97,18 +94,15 @@ #define LLONG long #endif -/*int snprintf (char *str, size_t count, const char *fmt, ...);*/ -/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ - -static void dopr (char *buffer, size_t maxlen, const char *format, - va_list args); -static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, +static size_t dopr(char *buffer, size_t maxlen, const char *format, + va_list args); +static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); -static void fmtint (char *buffer, size_t *currlen, size_t maxlen, +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags); -static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, +static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); -static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); /* * dopr(): poor man's version of doprintf @@ -140,774 +134,804 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); #define DP_C_LLONG 4 #define char_to_int(p) ((p)- '0') +#ifndef MAX #define MAX(p,q) (((p) >= (q)) ? (p) : (q)) +#endif -static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) +static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args) { - char ch; - LLONG value; - LDOUBLE fvalue; - char *strvalue; - int min; - int max; - int state; - int flags; - int cflags; - size_t currlen; - - state = DP_S_DEFAULT; - currlen = flags = cflags = min = 0; - max = -1; - ch = *format++; - - while (state != DP_S_DONE) - { - if ((ch == '\0') || (currlen >= maxlen)) - state = DP_S_DONE; - - switch(state) - { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - dopr_outch (buffer, &currlen, maxlen, ch); - ch = *format++; - break; - case DP_S_FLAGS: - switch (ch) - { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) - { - min = 10*min + char_to_int (ch); - ch = *format++; - } - else if (ch == '*') - { - min = va_arg (args, int); - ch = *format++; - state = DP_S_DOT; - } - else - state = DP_S_DOT; - break; - case DP_S_DOT: - if (ch == '.') - { - state = DP_S_MAX; - ch = *format++; - } - else - state = DP_S_MOD; - break; - case DP_S_MAX: - if (isdigit((unsigned char)ch)) - { - if (max < 0) - max = 0; - max = 10*max + char_to_int (ch); - ch = *format++; - } - else if (ch == '*') - { - max = va_arg (args, int); + char ch; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; ch = *format++; - state = DP_S_MOD; - } - else - state = DP_S_MOD; - break; - case DP_S_MOD: - switch (ch) - { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - break; - case 'l': - cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { /* It's a long long */ - cflags = DP_C_LLONG; - ch = *format++; + + while (state != DP_S_DONE) { + if (ch == '\0') + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch (buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10*min + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } else { + state = DP_S_DOT; + } + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else { + state = DP_S_MOD; + } + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10*max + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } else { + state = DP_S_MOD; + } + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { /* It's a long long */ + cflags = DP_C_LLONG; + ch = *format++; + } + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg (args, int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else if (cflags == DP_C_LLONG) + value = va_arg (args, LLONG); + else + value = va_arg (args, int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (long)va_arg (args, unsigned LLONG); + else + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, unsigned LLONG); + else + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, unsigned LLONG); + else + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + /* um, floating point? */ + fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + break; + case 'c': + dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); + break; + case 's': + strvalue = va_arg (args, char *); + if (max == -1) { + max = strlen(strvalue); + } + if (min > 0 && max >= 0 && min > max) max = min; + fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg (args, void *); + fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg (args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg (args, long int *); + *num = (long int)currlen; + } else if (cflags == DP_C_LLONG) { + LLONG *num; + num = va_arg (args, LLONG *); + *num = (LLONG)currlen; + } else { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch (buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } } - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - switch (ch) - { - case 'd': - case 'i': - if (cflags == DP_C_SHORT) - value = va_arg (args, short int); - else if (cflags == DP_C_LONG) - value = va_arg (args, long int); - else if (cflags == DP_C_LLONG) - value = va_arg (args, LLONG); - else - value = va_arg (args, int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'o': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg (args, unsigned short int); - else if (cflags == DP_C_LONG) - value = (long)va_arg (args, unsigned long int); - else if (cflags == DP_C_LLONG) - value = (long)va_arg (args, unsigned LLONG); - else - value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); - break; - case 'u': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg (args, unsigned short int); - else if (cflags == DP_C_LONG) - value = (long)va_arg (args, unsigned long int); - else if (cflags == DP_C_LLONG) - value = (LLONG)va_arg (args, unsigned LLONG); - else - value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'X': - flags |= DP_F_UP; - case 'x': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg (args, unsigned short int); - else if (cflags == DP_C_LONG) - value = (long)va_arg (args, unsigned long int); - else if (cflags == DP_C_LLONG) - value = (LLONG)va_arg (args, unsigned LLONG); - else - value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); - break; - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, LDOUBLE); - else - fvalue = va_arg (args, double); - /* um, floating point? */ - fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); - break; - case 'E': - flags |= DP_F_UP; - case 'e': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, LDOUBLE); - else - fvalue = va_arg (args, double); - break; - case 'G': - flags |= DP_F_UP; - case 'g': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, LDOUBLE); - else - fvalue = va_arg (args, double); - break; - case 'c': - dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); - break; - case 's': - strvalue = va_arg (args, char *); - if (max < 0) - max = maxlen; /* ie, no max */ - fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); - break; - case 'p': - strvalue = va_arg (args, void *); - fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); - break; - case 'n': - if (cflags == DP_C_SHORT) - { - short int *num; - num = va_arg (args, short int *); - *num = currlen; - } - else if (cflags == DP_C_LONG) - { - long int *num; - num = va_arg (args, long int *); - *num = (long int)currlen; - } - else if (cflags == DP_C_LLONG) - { - LLONG *num; - num = va_arg (args, LLONG *); - *num = (LLONG)currlen; - } - else - { - int *num; - num = va_arg (args, int *); - *num = currlen; - } - break; - case '%': - dopr_outch (buffer, &currlen, maxlen, ch); - break; - case 'w': - /* not supported yet, treat as next char */ - ch = *format++; - break; - default: - /* Unknown, skip */ - break; - } - ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; - break; - case DP_S_DONE: - break; - default: - /* hmm? */ - break; /* some picky compilers need this */ - } - } - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else - buffer[maxlen - 1] = '\0'; + if (maxlen != 0) { + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else if (maxlen > 0) + buffer[maxlen - 1] = '\0'; + } + + return currlen; } -static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, +static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { - int padlen, strln; /* amount to pad */ - int cnt = 0; - - if (value == 0) - { - value = "<NULL>"; - } - - for (strln = 0; value[strln]; ++strln); /* strlen */ - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - while ((padlen > 0) && (cnt < max)) - { - dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - ++cnt; - } - while (*value && (cnt < max)) - { - dopr_outch (buffer, currlen, maxlen, *value++); - ++cnt; - } - while ((padlen < 0) && (cnt < max)) - { - dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - ++cnt; - } + int padlen, strln; /* amount to pad */ + int cnt = 0; + +#ifdef DEBUG_SNPRINTF + printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); +#endif + if (value == 0) { + value = "<NULL>"; + } + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ -static void fmtint (char *buffer, size_t *currlen, size_t maxlen, +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags) { - int signvalue = 0; - unsigned long uvalue; - char convert[20]; - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - int caps = 0; - - if (max < 0) - max = 0; - - uvalue = value; - - if(!(flags & DP_F_UNSIGNED)) - { - if( value < 0 ) { - signvalue = '-'; - uvalue = -value; - } - else - if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else - if (flags & DP_F_SPACE) - signvalue = ' '; - } + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } else { + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + } - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ - - do { - convert[place++] = - (caps? "0123456789ABCDEF":"0123456789abcdef") - [uvalue % (unsigned)base ]; - uvalue = (uvalue / (unsigned)base ); - } while(uvalue && (place < 20)); - if (place == 20) place--; - convert[place] = 0; - - zpadlen = max - place; - spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); - if (zpadlen < 0) zpadlen = 0; - if (spadlen < 0) spadlen = 0; - if (flags & DP_F_ZERO) - { - zpadlen = MAX(zpadlen, spadlen); - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < 20)); + if (place == 20) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF - printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", - zpadlen, spadlen, min, max, place); + printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place); #endif - /* Spaces */ - while (spadlen > 0) - { - dopr_outch (buffer, currlen, maxlen, ' '); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); - - /* Zeros */ - if (zpadlen > 0) - { - while (zpadlen > 0) - { - dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - } - - /* Digits */ - while (place > 0) - dopr_outch (buffer, currlen, maxlen, convert[--place]); + /* Spaces */ + while (spadlen > 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch (buffer, currlen, maxlen, convert[--place]); - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - ++spadlen; - } + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } } -static LDOUBLE abs_val (LDOUBLE value) +static LDOUBLE abs_val(LDOUBLE value) { - LDOUBLE result = value; + LDOUBLE result = value; - if (value < 0) - result = -value; + if (value < 0) + result = -value; + + return result; +} - return result; +static LDOUBLE POW10(int exp) +{ + LDOUBLE result = 1; + + while (exp) { + result *= 10; + exp--; + } + + return result; } -static LDOUBLE pow10 (int exp) +static LLONG ROUND(LDOUBLE value) { - LDOUBLE result = 1; + LLONG intpart; - while (exp) - { - result *= 10; - exp--; - } - - return result; + intpart = (LLONG)value; + value = value - intpart; + if (value >= 0.5) intpart++; + + return intpart; } -static long round (LDOUBLE value) +/* a replacement for modf that doesn't need the math library. Should + be portable, but slow */ +static double my_modf(double x0, double *iptr) { - long intpart; + int i; + long l; + double x = x0; + double f = 1.0; + + for (i=0;i<100;i++) { + l = (long)x; + if (l <= (x+1) && l >= (x-1)) break; + x *= 0.1; + f *= 10.0; + } - intpart = (long)value; - value = value - intpart; - if (value >= 0.5) - intpart++; + if (i == 100) { + /* yikes! the number is beyond what we can handle. What do we do? */ + (*iptr) = 0; + return 0; + } + + if (i != 0) { + double i2; + double ret; - return intpart; + ret = my_modf(x0-l*f, &i2); + (*iptr) = l*f + i2; + return ret; + } + + (*iptr) = l; + return x - (*iptr); } + static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { - int signvalue = 0; - LDOUBLE ufvalue; -#ifndef HAVE_FCVT - char iconvert[20]; - char fconvert[20]; -#else - char iconvert[311]; - char fconvert[311]; - char *result; - int dec_pt, sig; - int r_length; -# ifdef HAVE_FCVTL - extern char *fcvtl(long double value, int ndigit, int *decpt, int *sign); -# else - extern char *fcvt(double value, int ndigit, int *decpt, int *sign); -# endif -#endif - int iplace = 0; - int fplace = 0; - int padlen = 0; /* amount to pad */ - int zpadlen = 0; - int caps = 0; - long intpart; - long fracpart; + int signvalue = 0; + double ufvalue; + char iconvert[311]; + char fconvert[311]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + int index; + double intpart; + double fracpart; + double temp; - /* - * AIX manpage says the default is 0, but Solaris says the default - * is 6, and sprintf on AIX defaults to 6 - */ - if (max < 0) - max = 6; - - ufvalue = abs_val (fvalue); - - if (fvalue < 0) - signvalue = '-'; - else - if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else - if (flags & DP_F_SPACE) - signvalue = ' '; + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val (fvalue); + + if (fvalue < 0) { + signvalue = '-'; + } else { + if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ + signvalue = '+'; + } else { + if (flags & DP_F_SPACE) + signvalue = ' '; + } + } #if 0 - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif -#ifndef HAVE_FCVT - intpart = (long)ufvalue; - - /* - * Sorry, we only support 9 digits past the decimal because of our - * conversion method - */ - if (max > 9) - max = 9; - - /* We "cheat" by converting the fractional part to integer by - * multiplying by a factor of 10 - */ - fracpart = round ((pow10 (max)) * (ufvalue - intpart)); - - if (fracpart >= pow10 (max)) - { - intpart++; - fracpart -= pow10 (max); - } - -#ifdef DEBUG_SNPRINTF - printf("fmtfp: %g %d.%d min=%d max=%d\n", - (double)fvalue, intpart, fracpart, min, max); +#if 0 + if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ #endif - /* Convert integer part */ - do { - iconvert[iplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; - intpart = (intpart / 10); - } while(intpart && (iplace < 20)); - if (iplace == 20) iplace--; - iconvert[iplace] = 0; - - /* Convert fractional part */ - do { - fconvert[fplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; - fracpart = (fracpart / 10); - } while(fracpart && (fplace < 20)); - if (fplace == 20) fplace--; - fconvert[fplace] = 0; -#else /* use fcvt() */ - if (max > 310) - max = 310; -# ifdef HAVE_FCVTL - result = fcvtl(ufvalue, max, &dec_pt, &sig); -# else - result = fcvt(ufvalue, max, &dec_pt, &sig); -# endif - - r_length = strlen(result); - - /* - * Fix broken fcvt implementation returns.. - */ - - if (r_length == 0) - { - result[0] = '0'; - result[1] = '\0'; - r_length = 1; - } - - if ( r_length < dec_pt ) - dec_pt = r_length; - - if (dec_pt <= 0) { - iplace = 1; - iconvert[0] = '0'; - iconvert[1] = '\0'; - - fplace = 0; - - while(r_length) - fconvert[fplace++] = result[--r_length]; - - while ((dec_pt < 0) && (fplace < max)) { - fconvert[fplace++] = '0'; - dec_pt++; + /* + * Sorry, we only support 16 digits past the decimal because of our + * conversion method + */ + if (max > 16) + max = 16; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + + temp = ufvalue; + my_modf(temp, &intpart); + + fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); + + if (fracpart >= POW10(max)) { + intpart++; + fracpart -= POW10(max); } - } else { - int c; - iplace=0; - for(c=dec_pt; c; iconvert[iplace++] = result[--c]) - ; - iconvert[iplace] = '\0'; - result += dec_pt; - fplace = 0; - - for(c=(r_length-dec_pt); c; fconvert[fplace++] = result[--c]) - ; - } -#endif /* fcvt */ + /* Convert integer part */ + do { + temp = intpart; + my_modf(intpart*0.1, &intpart); + temp = temp*0.1; + index = (int) ((temp -intpart +0.05)* 10.0); + /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ + /* printf ("%llf, %f, %x\n", temp, intpart, index); */ + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; + } while (intpart && (iplace < 311)); + if (iplace == 311) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + if (fracpart) + { + do { + temp = fracpart; + my_modf(fracpart*0.1, &fracpart); + temp = temp*0.1; + index = (int) ((temp -fracpart +0.05)* 10.0); + /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */ + /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */ + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; + } while(fracpart && (fplace < 311)); + if (fplace == 311) fplace--; + } + fconvert[fplace] = 0; - /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); - zpadlen = max - fplace; - if (zpadlen < 0) - zpadlen = 0; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justifty */ - - if ((flags & DP_F_ZERO) && (padlen > 0)) - { - if (signvalue) - { - dopr_outch (buffer, currlen, maxlen, signvalue); - --padlen; - signvalue = 0; - } - while (padlen > 0) - { - dopr_outch (buffer, currlen, maxlen, '0'); - --padlen; - } - } - while (padlen > 0) - { - dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - } - if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); - - while (iplace > 0) - dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); - + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + dopr_outch (buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); #ifdef DEBUG_SNPRINTF - printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); + printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); #endif - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - if (max > 0) { - dopr_outch (buffer, currlen, maxlen, '.'); - - while (fplace > 0) - dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); - } - - while (zpadlen > 0) - { - dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - - while (padlen < 0) - { - dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - } + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0) { + dopr_outch (buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + } + + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } } -static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) { - if (*currlen < maxlen) - buffer[(*currlen)++] = c; + if (*currlen < maxlen) { + buffer[(*currlen)] = c; + } + (*currlen)++; } -#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ -#ifndef HAVE_VSNPRINTF +#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) int vsnprintf (char *str, size_t count, const char *fmt, va_list args) { - str[0] = 0; - dopr(str, count, fmt, args); - return(strlen(str)); + return dopr(str, count, fmt, args); } -#endif /* !HAVE_VSNPRINTF */ - -#if 0 /* DONT USE SNPRINTF !!! */ -#ifndef HAVE_SNPRINTF -/* VARARGS3 */ -#ifdef HAVE_STDARGS - int snprintf (char *str,size_t count,const char *fmt,...) -#else - int snprintf (va_alist) va_dcl #endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) + int snprintf(char *str,size_t count,const char *fmt,...) { -#ifndef HAVE_STDARGS - char *str; - size_t count; - char *fmt; -#endif - VA_LOCAL_DECL; + size_t ret; + va_list ap; - VA_START (fmt); - VA_SHIFT (str, char *); - VA_SHIFT (count, size_t ); - VA_SHIFT (fmt, char *); - (void) vsnprintf(str, count, fmt, ap); - VA_END; - return(strlen(str)); + va_start(ap, fmt); + ret = vsnprintf(str, count, fmt, ap); + va_end(ap); + return ret; } #endif -#else - /* keep compilers happy about empty files */ - void dummy_snprintf(void) {} -#endif /* !HAVE_SNPRINTF */ +#endif -#ifdef TEST_SNPRINTF -#ifndef LONG_STRING -#define LONG_STRING 1024 +#ifndef HAVE_VASPRINTF + int vasprintf(char **ptr, const char *format, va_list ap) +{ + int ret; + + ret = vsnprintf(NULL, 0, format, ap); + if (ret <= 0) return ret; + + (*ptr) = (char *)malloc(ret+1); + if (!*ptr) return -1; + ret = vsnprintf(*ptr, ret+1, format, ap); + + return ret; +} #endif + + +#ifndef HAVE_ASPRINTF + int asprintf(char **ptr, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = vasprintf(ptr, format, ap); + va_end(ap); + + return ret; +} +#endif + +#ifdef TEST_SNPRINTF + + int sprintf(char *str,const char *fmt,...); + int main (void) { - char buf1[LONG_STRING]; - char buf2[LONG_STRING]; - char *fp_fmt[] = { - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - "%.0f", - "%.1f", - NULL - }; - double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, - 0.9996, 1.996, 4.136, 6442452944.1234, 0}; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - NULL - }; - long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; - int x, y; - int fail = 0; - int num = 0; - - printf ("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] != NULL ; x++) - for (y = 0; fp_nums[y] != 0 ; y++) - { - snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); - sprintf (buf2, fp_fmt[x], fp_nums[y]); - if (strcmp (buf1, buf2)) - { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", - fp_fmt[x], buf1, buf2); - fail++; - } - num++; - } - - for (x = 0; int_fmt[x] != NULL ; x++) - for (y = 0; int_nums[y] != 0 ; y++) - { - snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); - sprintf (buf2, int_fmt[x], int_nums[y]); - if (strcmp (buf1, buf2)) - { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", - int_fmt[x], buf1, buf2); - fail++; - } - num++; - } - printf ("%d tests failed out of %d.\n", fail, num); + char buf1[1024]; + char buf2[1024]; + char *fp_fmt[] = { + "%1.1f", + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + "%.0f", + "%f", + "-16.16f", + NULL + }; + double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + "%d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; + char *str_fmt[] = { + "10.5s", + "5.10s", + "10.1s", + "0.10s", + "10.0s", + "1.10s", + "%s", + "%.1s", + "%.10s", + "%10s", + NULL + }; + char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; + int x, y; + int fail = 0; + int num = 0; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] ; x++) { + for (y = 0; fp_nums[y] != 0 ; y++) { + int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]); + int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", + fp_fmt[x], buf1, buf2); + fail++; + } + if (l1 != l2) { + printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]); + fail++; + } + num++; + } + } + + for (x = 0; int_fmt[x] ; x++) { + for (y = 0; int_nums[y] != 0 ; y++) { + int l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]); + int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); + sprintf (buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", + int_fmt[x], buf1, buf2); + fail++; + } + if (l1 != l2) { + printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]); + fail++; + } + num++; + } + } + + for (x = 0; str_fmt[x] ; x++) { + for (y = 0; str_vals[y] != 0 ; y++) { + int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]); + int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); + sprintf (buf2, str_fmt[x], str_vals[y]); + if (strcmp (buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", + str_fmt[x], buf1, buf2); + fail++; + } + if (l1 != l2) { + printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]); + fail++; + } + num++; + } + } + + printf ("%d tests failed out of %d.\n", fail, num); + + printf("seeing how many digits we support\n"); + { + double v0 = 0.12345678901234567890123456789012345678901; + for (x=0; x<100; x++) { + snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x)); + sprintf(buf2, "%1.1f", v0*pow(10, x)); + if (strcmp(buf1, buf2)) { + printf("we seem to support %d digits\n", x-1); + break; + } + } + } + + return 0; } #endif /* SNPRINTF_TEST */ - diff --git a/source/lib/substitute.c b/source/lib/substitute.c index 6abdeea114c..25be4b030f7 100644 --- a/source/lib/substitute.c +++ b/source/lib/substitute.c @@ -172,9 +172,21 @@ void standard_sub_basic(char *str) fstring pidstr; for (s=str; (p=strchr(s, '%'));s=p) { + fstring tmp_str; + int l = sizeof(pstring) - (int)(p-str); switch (*(p+1)) { + case 'U' : + fstrcpy(tmp_str, sam_logon_in_ssb?samlogon_user:current_user_info.smb_name); + strlower(tmp_str); + string_sub(p,"%U",tmp_str,l); + break; + case 'D' : + fstrcpy(tmp_str, current_user_info.domain); + strupper(tmp_str); + string_sub(p,"%D", tmp_str,l); + break; case 'I' : string_sub(p,"%I", client_addr(),l); break; case 'L' : string_sub(p,"%L", local_machine,l); break; case 'M' : string_sub(p,"%M", client_name(),l); break; @@ -212,7 +224,6 @@ void standard_sub_advanced(int snum, char *user, char *connectpath, gid_t gid, c int l = sizeof(pstring) - (int)(p-str); switch (*(p+1)) { - case 'U' : string_sub(p,"%U",sam_logon_in_ssb?samlogon_user:current_user_info.smb_name,l); break; case 'G' : if ((pass = Get_Pwnam(user,False))!=NULL) { string_sub(p,"%G",gidtoname(pass->pw_gid),l); @@ -220,7 +231,6 @@ void standard_sub_advanced(int snum, char *user, char *connectpath, gid_t gid, c p += 2; } break; - case 'D' : string_sub(p,"%D", current_user_info.domain,l); break; case 'N' : string_sub(p,"%N", automount_server(user),l); break; case 'H': if ((home = get_user_home_dir(user))) { diff --git a/source/lib/sysacls.c b/source/lib/sysacls.c index d1b6e58b409..0770a8856a2 100644 --- a/source/lib/sysacls.c +++ b/source/lib/sysacls.c @@ -45,8 +45,9 @@ extern int DEBUGLEVEL; int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual) int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) int sys_acl_valid( SMB_ACL_T theacl ) - int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) + int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) int sys_acl_set_fd( int fd, SMB_ACL_T theacl) + int sys_acl_delete_def_file(const char *path) This next one is not POSIX complient - but we *have* to have it ! More POSIX braindamage. @@ -160,7 +161,7 @@ int sys_acl_valid( SMB_ACL_T theacl ) return acl_valid(theacl); } -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) { return acl_set_file(name, acltype, theacl); } @@ -170,6 +171,11 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl) return acl_set_fd(fd, theacl); } +int sys_acl_delete_def_file(const char *name) +{ + return acl_delete_def_file(name); +} + int sys_acl_free_text(char *text) { return acl_free(text); @@ -649,17 +655,40 @@ int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d) return 0; } -int sys_acl_valid(SMB_ACL_T acl_d) +/* + * sort the ACL and check it for validity + * + * if it's a minimal ACL with only 4 entries then we + * need to recalculate the mask permissions to make + * sure that they are the same as the GROUP_OBJ + * permissions as required by the UnixWare acl() system call. + * + * (note: since POSIX allows minimal ACLs which only contain + * 3 entries - ie there is no mask entry - we should, in theory, + * check for this and add a mask entry if necessary - however + * we "know" that the caller of this interface always specifies + * a mask so, in practice "this never happens" (tm) - if it *does* + * happen aclsort() will fail and return an error and someone will + * have to fix it ...) + */ + +static int acl_sort(SMB_ACL_T acl_d) { - if (aclsort(acl_d->count, 1, acl_d->acl) != 0) { + int fixmask = (acl_d->count <= 4); + + if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) { errno = EINVAL; return -1; } - return 0; } + +int sys_acl_valid(SMB_ACL_T acl_d) +{ + return acl_sort(acl_d); +} -int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) +int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) { struct stat s; struct acl *acl_p; @@ -672,7 +701,7 @@ int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) return -1; } - if (stat(name, &s) != 0) { + if (acl_sort(acl_d) != 0) { return -1; } @@ -684,6 +713,9 @@ int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) * since the acl() system call will replace both * the access ACLs and the default ACLs (if any) */ + if (stat(name, &s) != 0) { + return -1; + } if (S_ISDIR(s.st_mode)) { SMB_ACL_T acc_acl; SMB_ACL_T def_acl; @@ -692,13 +724,11 @@ int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) if (type == SMB_ACL_TYPE_ACCESS) { acc_acl = acl_d; - def_acl = - tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT); + def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT); } else { def_acl = acl_d; - acc_acl = - tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS); + acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS); } if (tmp_acl == NULL) { @@ -708,9 +738,8 @@ int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) /* * allocate a temporary buffer for the complete ACL */ - acl_count = acc_acl->count + def_acl->count; - acl_p = - acl_buf = malloc(acl_count * sizeof(acl_buf[0])); + acl_count = acc_acl->count + def_acl->count; + acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0])); if (acl_buf == NULL) { sys_acl_free_acl(tmp_acl); @@ -741,12 +770,7 @@ int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) return -1; } - if (aclsort(acl_count, 1, acl_p) != 0) { - errno = EINVAL; - ret = -1; - } else { - ret = acl(name, SETACL, acl_count, acl_p); - } + ret = acl(name, SETACL, acl_count, acl_p); if (acl_buf) { free(acl_buf); @@ -757,14 +781,33 @@ int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) int sys_acl_set_fd(int fd, SMB_ACL_T acl_d) { - if (aclsort(acl_d->count, 1, acl_d->acl) != 0) { - errno = EINVAL; + if (acl_sort(acl_d) != 0) { return -1; } return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]); } +int sys_acl_delete_def_file(const char *path) +{ + SMB_ACL_T acl_d; + int ret; + + /* + * fetching the access ACL and rewriting it has + * the effect of deleting the default ACL + */ + if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) { + return -1; + } + + ret = acl(path, SETACL, acl_d->count, acl_d->acl); + + sys_acl_free_acl(acl_d); + + return ret; +} + int sys_acl_free_text(char *text) { free(text); @@ -1003,7 +1046,7 @@ int sys_acl_valid(SMB_ACL_T acl_d) return acl_valid(acl_d->aclp); } -int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) +int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) { return acl_set_file(name, type, acl_d->aclp); } @@ -1013,6 +1056,11 @@ int sys_acl_set_fd(int fd, SMB_ACL_T acl_d) return acl_set_fd(fd, acl_d->aclp); } +int sys_acl_delete_def_file(const char *name) +{ + return acl_delete_def_file(name); +} + int sys_acl_free_text(char *text) { return acl_free(text); @@ -1032,225 +1080,6 @@ int sys_acl_free_qualifier(void *qual) return 0; } -#elif defined(HAVE_XFS_ACLS) -/* For Linux SGI/XFS Filesystems - * contributed by J Trostel, Connex - * */ - -/* based on the implementation for Solaris by Toomas Soome.. which is - * based on the implementation by Micheal Davidson for Unixware... - * - * Linux XFS is a 'work-in-progress' - * This interface may change... - * You've been warned ;-> */ - -/* First, do the identity mapping */ - -int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p) -{ - if( acl_get_entry( the_acl, entry_id, entry_p) >= 0) { - return 1; - } - else { - return -1; - } -} - -SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) -{ - return acl_get_file( path_p, type); -} - -SMB_ACL_T sys_acl_get_fd(int fd) -{ - return acl_get_fd(fd); -} - -char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen) -{ - return acl_to_text( the_acl, plen); -} - -int sys_acl_valid( SMB_ACL_T theacl ) -{ - return acl_valid(theacl); -} - -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) -{ - return acl_set_file(name, acltype, theacl); -} - -int sys_acl_set_fd( int fd, SMB_ACL_T theacl) -{ - return acl_set_fd(fd, theacl); -} - -/* Now the functions I need to define for XFS */ - -int sys_acl_create_entry( SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p) -{ - acl_t acl, newacl; - acl_entry_t ace; - int cnt; - - acl = *acl_p; - ace = *entry_p; - - if((*acl_p == NULL) || (ace == NULL)){ - errno = EINVAL; - return -1; - } - - cnt = acl->acl_cnt; - if( (cnt + 1) > ACL_MAX_ENTRIES ){ - errno = ENOSPC; - return -1; - } - - newacl = (acl_t)malloc(sizeof(struct acl)); - if(newacl == NULL){ - errno = ENOMEM; - return -1; - } - - *newacl = *acl; - newacl->acl_entry[cnt] = *ace; - newacl->acl_cnt = cnt + 1; - - acl_free(*acl_p); - *acl_p = newacl; - *entry_p = &newacl->acl_entry[cnt]; - return 0; -} - - -int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) -{ - *tag_type_p = entry_d->ae_tag; - return 0; -} - -int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - *permset_p = &entry_d->ae_perm; - return 0; -} - -void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d) -{ - if (entry_d->ae_tag != SMB_ACL_USER - && entry_d->ae_tag != SMB_ACL_GROUP) { - errno = EINVAL; - return NULL; - } - return &entry_d->ae_id; -} - -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset) -{ - *permset = 0; - return 0; -} - -int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return (*permset & perm); -} - -int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - - /* TO DO: Add in ALL possible permissions here */ - /* TO DO: Include extended ones!! */ - - if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE && perm != SMB_ACL_EXECUTE) { - errno = EINVAL; - return -1; - } - - if(permset == NULL) { - errno = EINVAL; - return -1; - } - - *permset |= perm; - - return 0; -} - -SMB_ACL_T sys_acl_init( int count) -{ - SMB_ACL_T a; - if((count > ACL_MAX_ENTRIES) || (count < 0)) { - errno = EINVAL; - return NULL; - } - else { - a = (struct acl *)malloc(sizeof(struct acl)); /* where is this memory freed? */ - a->acl_cnt = 0; - return a; - } -} - -int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type) -{ - - switch (tag_type) { - case SMB_ACL_USER: - case SMB_ACL_USER_OBJ: - case SMB_ACL_GROUP: - case SMB_ACL_GROUP_OBJ: - case SMB_ACL_OTHER: - case SMB_ACL_MASK: - entry_d->ae_tag = tag_type; - break; - default: - errno = EINVAL; - return -1; - } - return 0; -} - -int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry_d, void *qual_p) -{ - if(entry_d->ae_tag != SMB_ACL_GROUP && - entry_d->ae_tag != SMB_ACL_USER) { - errno = EINVAL; - return -1; - } - - entry_d->ae_id = *((uid_t *)qual_p); - - return 0; -} - -int sys_acl_set_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d) -{ - /* TO DO: expand to extended permissions eventually! */ - - if(*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) { - return EINVAL; - } - - return 0; -} - -int sys_acl_free_text(char *text) -{ - return acl_free(text); -} - -int sys_acl_free_acl(SMB_ACL_T the_acl) -{ - return acl_free(the_acl); -} - -int sys_acl_free_qualifier(void *qual) -{ - return 0; -} - #elif defined(HAVE_AIX_ACLS) /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */ @@ -1914,7 +1743,7 @@ int sys_acl_valid( SMB_ACL_T theacl ) return(0); } -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) { struct acl_entry_link *acl_entry_link = NULL; struct acl *file_acl = NULL; @@ -2098,6 +1927,12 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl) return(rc); } +int sys_acl_delete_def_file(const char *name) +{ + /* AIX has no default ACL */ + return 0; +} + int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) { return(*permset & perm); @@ -2234,7 +2069,7 @@ int sys_acl_valid( SMB_ACL_T theacl ) return -1; } -int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) { errno = ENOSYS; return -1; @@ -2246,6 +2081,12 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl) return -1; } +int sys_acl_delete_def_file(const char *name) +{ + errno = ENOSYS; + return -1; +} + int sys_acl_free_acl(SMB_ACL_T the_acl) { errno = ENOSYS; diff --git a/source/lib/system.c b/source/lib/system.c index 0c627b2f659..a402af77c9b 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -265,6 +265,34 @@ char *sys_getwd(char *s) } /******************************************************************* +system wrapper for symlink +********************************************************************/ + +int sys_symlink(const char *oldpath, const char *newpath) +{ +#ifndef HAVE_SYMLINK + errno = ENOSYS; + return -1; +#else + return symlink(oldpath, newpath); +#endif +} + +/******************************************************************* +system wrapper for readlink +********************************************************************/ + +int sys_readlink(const char *path, char *buf, size_t bufsiz) +{ +#ifndef HAVE_READLINK + errno = ENOSYS; + return -1; +#else + return readlink(path, buf, bufsiz); +#endif +} + +/******************************************************************* chown isn't used much but OS/2 doesn't have it ********************************************************************/ @@ -583,6 +611,9 @@ int sys_setgroups(int setlen, gid_t *gidset) struct saved_pw { fstring pw_name; fstring pw_passwd; + fstring pw_gecos; + pstring pw_dir; + pstring pw_shell; struct passwd pass; }; @@ -594,6 +625,26 @@ static int num_lookups; /* Counter so we don't always use cache. */ #define PW_RET_CACHE_MAX_LOOKUPS 100 #endif +static void copy_pwent(struct saved_pw *dst, struct passwd *pass) +{ + memcpy((char *)&dst->pass, pass, sizeof(struct passwd)); + + fstrcpy(dst->pw_name, pass->pw_name); + dst->pass.pw_name = dst->pw_name; + + fstrcpy(dst->pw_passwd, pass->pw_passwd); + dst->pass.pw_passwd = dst->pw_passwd; + + fstrcpy(dst->pw_gecos, pass->pw_gecos); + dst->pass.pw_gecos = dst->pw_gecos; + + pstrcpy(dst->pw_dir, pass->pw_dir); + dst->pass.pw_dir = dst->pw_dir; + + pstrcpy(dst->pw_shell, pass->pw_shell); + dst->pass.pw_shell = dst->pw_shell; +} + static struct passwd *setup_pwret(struct passwd *pass) { if (pass == NULL) { @@ -604,25 +655,13 @@ static struct passwd *setup_pwret(struct passwd *pass) return NULL; } - /* this gets the uid, gid and null pointers */ - - memcpy((char *)&pw_mod.pass, pass, sizeof(struct passwd)); - fstrcpy(pw_mod.pw_name, pass->pw_name); - pw_mod.pass.pw_name = pw_mod.pw_name; - fstrcpy(pw_mod.pw_passwd, pass->pw_passwd); - pw_mod.pass.pw_passwd = pw_mod.pw_passwd; - + copy_pwent( &pw_mod, pass); if (pass != &pw_cache.pass) { /* If it's a cache miss we must also refill the cache. */ - memcpy((char *)&pw_cache.pass, pass, sizeof(struct passwd)); - fstrcpy(pw_cache.pw_name, pass->pw_name); - pw_cache.pass.pw_name = pw_cache.pw_name; - fstrcpy(pw_cache.pw_passwd, pass->pw_passwd); - pw_cache.pass.pw_passwd = pw_cache.pw_passwd; - + copy_pwent( &pw_cache, pass); num_lookups = 1; } else { diff --git a/source/lib/talloc.c b/source/lib/talloc.c index 54a3d8ed769..a8ee481744b 100644 --- a/source/lib/talloc.c +++ b/source/lib/talloc.c @@ -35,10 +35,7 @@ #include "includes.h" -#define TALLOC_ALIGN 32 -#define TALLOC_CHUNK_SIZE (0x2000) - -/* initialissa talloc context. */ +/* initialise talloc context. */ TALLOC_CTX *talloc_init(void) { TALLOC_CTX *t; @@ -56,43 +53,55 @@ TALLOC_CTX *talloc_init(void) void *talloc(TALLOC_CTX *t, size_t size) { void *p; - if (size == 0) - { - /* debugging value used to track down - memory problems. BAD_PTR is defined - in talloc.h */ - p = BAD_PTR; - return p; - } + struct talloc_chunk *tc; - /* normal code path */ - size = (size + (TALLOC_ALIGN-1)) & ~(TALLOC_ALIGN-1); + if (size == 0) return NULL; - if (!t->list || (t->list->total_size - t->list->alloc_size) < size) { - struct talloc_chunk *c; - size_t asize = (size + (TALLOC_CHUNK_SIZE-1)) & ~(TALLOC_CHUNK_SIZE-1); + p = malloc(size); + if (!p) return p; - c = (struct talloc_chunk *)malloc(sizeof(*c)); - if (!c) return NULL; - c->next = t->list; - c->ptr = (void *)malloc(asize); - if (!c->ptr) { - free(c); - return NULL; - } - c->alloc_size = 0; - c->total_size = asize; - t->list = c; - t->total_alloc_size += asize; + tc = malloc(sizeof(*tc)); + if (!tc) { + free(p); + return NULL; } - p = ((char *)t->list->ptr) + t->list->alloc_size; - t->list->alloc_size += size; + tc->ptr = p; + tc->size = size; + tc->next = t->list; + t->list = tc; + t->total_alloc_size += size; - return p; } +/* a talloc version of realloc */ +void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size) +{ + struct talloc_chunk *tc; + + /* size zero is equivalent to free() */ + if (size == 0) + return NULL; + + /* realloc(NULL) is equavalent to malloc() */ + if (ptr == NULL) + return talloc(t, size); + + for (tc=t->list; tc; tc=tc->next) { + if (tc->ptr == ptr) { + ptr = realloc(ptr, size); + if (ptr) { + t->total_alloc_size += (size - tc->size); + tc->size = size; + tc->ptr = ptr; + } + return ptr; + } + } + return NULL; +} + /* destroy a whole pool */ void talloc_destroy_pool(TALLOC_CTX *t) { @@ -103,7 +112,7 @@ void talloc_destroy_pool(TALLOC_CTX *t) while (t->list) { c = t->list->next; - free(t->list->ptr); + if (t->list->ptr) free(t->list->ptr); free(t->list); t->list = c; } @@ -118,14 +127,13 @@ void talloc_destroy(TALLOC_CTX *t) if (!t) return; talloc_destroy_pool(t); + memset(t, 0, sizeof(*t)); free(t); } /* return the current total size of the pool. */ size_t talloc_pool_size(TALLOC_CTX *t) { - if (!t->list) - return 0; return t->total_alloc_size; } @@ -152,3 +160,9 @@ void *talloc_memdup(TALLOC_CTX *t, void *p, size_t size) return newp; } + +/* strdup with a talloc */ +char *talloc_strdup(TALLOC_CTX *t, char *p) +{ + return talloc_memdup(t, p, strlen(p) + 1); +} diff --git a/source/lib/ufc.c b/source/lib/ufc.c index 86cb41a10c7..ecc04d9e97c 100644 --- a/source/lib/ufc.c +++ b/source/lib/ufc.c @@ -282,9 +282,7 @@ static ufc_long longmask[32] = { * bzero and some don't have memset. */ -static void clearmem(start, cnt) - char *start; - int cnt; +static void clearmem(char *start, int cnt) { while(cnt--) *start++ = '\0'; } @@ -300,7 +298,7 @@ static int initialized = 0; * by fcrypt users. */ -static void ufc_init_des() +static void ufc_init_des(void) { int comes_from_bit; int bit, sg; ufc_long j; @@ -351,13 +349,13 @@ static void ufc_init_des() clearmem((char*)eperm32tab, sizeof(eperm32tab)); for(bit = 0; bit < 48; bit++) { - ufc_long mask1,comes_from; + ufc_long inner_mask1,comes_from; comes_from = perm32[esel[bit]-1]-1; - mask1 = bytemask[comes_from % 8]; + inner_mask1 = bytemask[comes_from % 8]; for(j = 256; j--;) { - if(j & mask1) + if(j & inner_mask1) eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24); } } @@ -432,7 +430,7 @@ static void ufc_init_des() clearmem((char*)efp, sizeof efp); for(bit = 0; bit < 64; bit++) { int o_bit, o_long; - ufc_long word_value, mask1, mask2; + ufc_long word_value, inner_mask1, inner_mask2; int comes_from_f_bit, comes_from_e_bit; int comes_from_word, bit_within_word; @@ -452,12 +450,12 @@ static void ufc_init_des() comes_from_word = comes_from_e_bit / 6; /* 0..15 */ bit_within_word = comes_from_e_bit % 6; /* 0..5 */ - mask1 = longmask[bit_within_word + 26]; - mask2 = longmask[o_bit]; + inner_mask1 = longmask[bit_within_word + 26]; + inner_mask2 = longmask[o_bit]; for(word_value = 64; word_value--;) { - if(word_value & mask1) - efp[comes_from_word][word_value][o_long] |= mask2; + if(word_value & inner_mask1) + efp[comes_from_word][word_value][o_long] |= inner_mask2; } } initialized++; @@ -469,9 +467,7 @@ static void ufc_init_des() */ #ifdef _UFC_32_ -static void shuffle_sb(k, saltbits) - long32 *k; - ufc_long saltbits; +static void shuffle_sb(long32 *k, ufc_long saltbits) { ufc_long j; long32 x; for(j=4096; j--;) { @@ -483,9 +479,7 @@ static void shuffle_sb(k, saltbits) #endif #ifdef _UFC_64_ -static void shuffle_sb(k, saltbits) - long64 *k; - ufc_long saltbits; +static void shuffle_sb(long64 *k, ufc_long saltbits) { ufc_long j; long64 x; for(j=4096; j--;) { @@ -504,9 +498,9 @@ static unsigned char current_salt[3] = "&&"; /* invalid value */ static ufc_long current_saltbits = 0; static int direction = 0; -static void setup_salt(char *s1) +static void setup_salt(const char *s1) { ufc_long i, j, saltbits; - unsigned char *s2 = (unsigned char *)s1; + const unsigned char *s2 = (const unsigned char *)s1; if(!initialized) ufc_init_des(); @@ -544,8 +538,7 @@ static void setup_salt(char *s1) current_saltbits = saltbits; } -static void ufc_mk_keytab(key) - char *key; +static void ufc_mk_keytab(char *key) { ufc_long v1, v2, *k1; int i; #ifdef _UFC_32_ @@ -594,8 +587,7 @@ static void ufc_mk_keytab(key) * Undo an extra E selection and do final permutations */ -ufc_long *_ufc_dofinalperm(l1, l2, r1, r2) - ufc_long l1,l2,r1,r2; +ufc_long *_ufc_dofinalperm(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2) { ufc_long v1, v2, x; static ufc_long ary[2]; @@ -633,9 +625,7 @@ ufc_long *_ufc_dofinalperm(l1, l2, r1, r2) * prefixing with the salt */ -static char *output_conversion(v1, v2, salt) - ufc_long v1, v2; - char *salt; +static char *output_conversion(ufc_long v1, ufc_long v2, const char *salt) { static char outbuf[14]; int i, s; @@ -663,7 +653,7 @@ static char *output_conversion(v1, v2, salt) static ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long); -char *ufc_crypt(char *key,char *salt) +char *ufc_crypt(const char *key,const char *salt) { ufc_long *s; char ktab[9]; @@ -703,8 +693,7 @@ extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; #define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) -static ufc_long *_ufc_doit(l1, l2, r1, r2, itr) - ufc_long l1, l2, r1, r2, itr; +static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) { int i; long32 s, *k; @@ -743,8 +732,7 @@ extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; #define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) -static ufc_long *_ufc_doit(l1, l2, r1, r2, itr) - ufc_long l1, l2, r1, r2, itr; +static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) { int i; long64 l, r, s, *k; diff --git a/source/lib/util.c b/source/lib/util.c index 8edb6db1157..453bccdd361 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -335,12 +335,31 @@ void smb_setlen(char *buf,int len) ********************************************************************/ int set_message(char *buf,int num_words,int num_bytes,BOOL zero) { - if (zero) - memset(buf + smb_size,'\0',num_words*2 + num_bytes); - CVAL(buf,smb_wct) = num_words; - SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); - smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); - return (smb_size + num_words*2 + num_bytes); + if (zero) + memset(buf + smb_size,'\0',num_words*2 + num_bytes); + CVAL(buf,smb_wct) = num_words; + SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); + smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); + return (smb_size + num_words*2 + num_bytes); +} + +/******************************************************************* + setup only the byte count for a smb message +********************************************************************/ +void set_message_bcc(char *buf,int num_bytes) +{ + int num_words = CVAL(buf,smb_wct); + SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); + smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); +} + +/******************************************************************* + setup only the byte count for a smb message, using the end of the + message as a marker +********************************************************************/ +void set_message_end(void *outbuf,void *end_ptr) +{ + set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf))); } /******************************************************************* @@ -784,13 +803,13 @@ uint32 interpret_addr(char *str) res = inet_addr(str); } else { /* otherwise assume it's a network name of some sort and use - Get_Hostbyname */ - if ((hp = Get_Hostbyname(str)) == 0) { - DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str)); + sys_gethostbyname */ + if ((hp = sys_gethostbyname(str)) == 0) { + DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str)); return 0; } if(hp->h_addr == NULL) { - DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str)); + DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str)); return 0; } putip((char *)&res,(char *)hp->h_addr); @@ -977,67 +996,6 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask) /**************************************************************************** -a wrapper for gethostbyname() that tries with all lower and all upper case -if the initial name fails -****************************************************************************/ -struct hostent *Get_Hostbyname(const char *name) -{ - char *name2 = strdup(name); - struct hostent *ret; - - if (!name2) - { - DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n")); - exit(0); - } - - - /* - * This next test is redundent and causes some systems (with - * broken isalnum() calls) problems. - * JRA. - */ - -#if 0 - if (!isalnum(*name2)) - { - free(name2); - return(NULL); - } -#endif /* 0 */ - - ret = sys_gethostbyname(name2); - if (ret != NULL) - { - free(name2); - return(ret); - } - - /* try with all lowercase */ - strlower(name2); - ret = sys_gethostbyname(name2); - if (ret != NULL) - { - free(name2); - return(ret); - } - - /* try with all uppercase */ - strupper(name2); - ret = sys_gethostbyname(name2); - if (ret != NULL) - { - free(name2); - return(ret); - } - - /* nothing works :-( */ - free(name2); - return(NULL); -} - - -/**************************************************************************** check if a process exists. Does this work on all unixes? ****************************************************************************/ @@ -1095,13 +1053,15 @@ uid_t nametouid(char *name) uid_t u; u = (uid_t)strtol(name, &p, 0); - if (p != name) return u; + if ((p != name) && (*p == '\0')) + return u; if (winbind_nametouid(&u, name)) return u; pass = sys_getpwnam(name); - if (pass) return(pass->pw_uid); + if (pass) + return(pass->pw_uid); return (uid_t)-1; } @@ -1117,13 +1077,15 @@ gid_t nametogid(char *name) gid_t g; g = (gid_t)strtol(name, &p, 0); - if (p != name) return g; + if ((p != name) && (*p == '\0')) + return g; if (winbind_nametogid(&g, name)) return g; grp = getgrnam(name); - if (grp) return(grp->gr_gid); + if (grp) + return(grp->gr_gid); return (gid_t)-1; } @@ -1168,7 +1130,9 @@ char *readdirname(DIR *p) { static pstring buf; - memcpy(buf, dname, NAMLEN(ptr)+1); + int len = NAMLEN(ptr); + memcpy(buf, dname, len); + buf[len] = 0; dname = buf; } @@ -1714,34 +1678,6 @@ BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name) /***************************************************************** -like mktemp() but make sure that no % characters are used -% characters are bad for us because of the macro subs - *****************************************************************/ -char *smbd_mktemp(char *template) -{ - char *p = mktemp(template); - char *p2; - SMB_STRUCT_STAT st; - - if (!p) return NULL; - - while ((p2=strchr(p,'%'))) { - p2[0] = 'A'; - while (sys_stat(p,&st) == 0 && p2[0] < 'Z') { - /* damn, it exists */ - p2[0]++; - } - if (p2[0] == 'Z') { - /* oh well ... better return something */ - p2[0] = '%'; - return p; - } - } - - return p; -} - -/***************************************************************** possibly replace mkstemp if it is broken *****************************************************************/ int smb_mkstemp(char *template) @@ -1750,8 +1686,8 @@ int smb_mkstemp(char *template) return mkstemp(template); #else /* have a reasonable go at emulating it. Hope that - the system mktemp() isn't completly hopeless */ - char *p = smbd_mktemp(template); + the system mktemp() isn't completly hopeless */ + char *p = mktemp(template); if (!p) return -1; return open(p, O_CREAT|O_EXCL|O_RDWR, 0600); #endif diff --git a/source/lib/util_seaccess.c b/source/lib/util_seaccess.c index e1b18460e24..8b75a5f4876 100644 --- a/source/lib/util_seaccess.c +++ b/source/lib/util_seaccess.c @@ -106,14 +106,14 @@ static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired, include other bits requested. **********************************************************************************/ -static BOOL get_max_access( SEC_ACL *acl, NT_USER_TOKEN *token, uint32 *granted, uint32 desired, uint32 *status) +static BOOL get_max_access( SEC_ACL *the_acl, NT_USER_TOKEN *token, uint32 *granted, uint32 desired, uint32 *status) { uint32 acc_denied = 0; uint32 acc_granted = 0; size_t i; - for ( i = 0 ; i < acl->num_aces; i++) { - SEC_ACE *ace = &acl->ace[i]; + for ( i = 0 ; i < the_acl->num_aces; i++) { + SEC_ACE *ace = &the_acl->ace[i]; uint32 mask = ace->info.mask; if (!token_sid_in_ace( token, ace)) @@ -206,7 +206,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, { extern NT_USER_TOKEN anonymous_token; size_t i; - SEC_ACL *acl; + SEC_ACL *the_acl; fstring sid_str; NT_USER_TOKEN *token = user->nt_user_token ? user->nt_user_token : &anonymous_token; uint32 tmp_acc_desired = acc_desired; @@ -259,15 +259,15 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, } } - acl = sd->dacl; + the_acl = sd->dacl; if (tmp_acc_desired & MAXIMUM_ALLOWED_ACCESS) { tmp_acc_desired &= ~MAXIMUM_ALLOWED_ACCESS; - return get_max_access( acl, token, acc_granted, tmp_acc_desired, status); + return get_max_access( the_acl, token, acc_granted, tmp_acc_desired, status); } - for ( i = 0 ; i < acl->num_aces && tmp_acc_desired != 0; i++) { - SEC_ACE *ace = &acl->ace[i]; + for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) { + SEC_ACE *ace = &the_acl->ace[i]; DEBUG(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n", (unsigned int)i, ace->type, ace->flags, @@ -310,7 +310,7 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, { SEC_DESC_BUF *sdb; SEC_DESC *sd; - SEC_ACL *new_dacl, *acl; + SEC_ACL *new_dacl, *the_acl; SEC_ACE *new_ace_list = NULL; int new_ace_list_ndx = 0, i; size_t size; @@ -319,13 +319,13 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, sacl should also be processed but this is left out as sacls are not implemented in Samba at the moment.*/ - acl = parent_ctr->dacl; + the_acl = parent_ctr->dacl; - if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * acl->num_aces))) + if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * the_acl->num_aces))) return NULL; - for (i = 0; acl && i < acl->num_aces; i++) { - SEC_ACE *ace = &acl->ace[i]; + for (i = 0; the_acl && i < the_acl->num_aces; i++) { + SEC_ACE *ace = &the_acl->ace[i]; SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx]; uint8 new_flags = 0; BOOL inherit = False; diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c index 068be684f36..54b819b1cc6 100644 --- a/source/lib/util_sec.c +++ b/source/lib/util_sec.c @@ -42,8 +42,34 @@ extern int DEBUGLEVEL; #define DEBUG(x, y) printf y #define smb_panic(x) exit(1) +#define BOOL int #endif +/* are we running as non-root? This is used by the regresison test code, + and potentially also for sites that want non-root smbd */ +static uid_t initial_uid; + +/**************************************************************************** +remember what uid we got started as - this allows us to run correctly +as non-root while catching trapdoor systems +****************************************************************************/ +void sec_init(void) +{ + initial_uid = geteuid(); + if (initial_uid != (uid_t)0) { + /* the DEBUG() subsystem has not been initialised when this is called */ + fprintf(stderr, "WARNING: running as non-root. Some functionality will be missing\n"); + } +} + +/**************************************************************************** +are we running in non-root mode? +****************************************************************************/ +BOOL non_root_mode(void) +{ + return (initial_uid != (uid_t)0); +} + /**************************************************************************** abort if we haven't set the uid correctly ****************************************************************************/ @@ -51,11 +77,13 @@ static void assert_uid(uid_t ruid, uid_t euid) { if ((euid != (uid_t)-1 && geteuid() != euid) || (ruid != (uid_t)-1 && getuid() != ruid)) { - DEBUG(0,("Failed to set uid privileges to (%d,%d) now set to (%d,%d)\n", - (int)ruid, (int)euid, - (int)getuid(), (int)geteuid())); - smb_panic("failed to set uid\n"); - exit(1); + if (!non_root_mode()) { + DEBUG(0,("Failed to set uid privileges to (%d,%d) now set to (%d,%d)\n", + (int)ruid, (int)euid, + (int)getuid(), (int)geteuid())); + smb_panic("failed to set uid\n"); + exit(1); + } } } @@ -66,12 +94,14 @@ static void assert_gid(gid_t rgid, gid_t egid) { if ((egid != (gid_t)-1 && getegid() != egid) || (rgid != (gid_t)-1 && getgid() != rgid)) { - DEBUG(0,("Failed to set gid privileges to (%d,%d) now set to (%d,%d) uid=(%d,%d)\n", - (int)rgid, (int)egid, - (int)getgid(), (int)getegid(), - (int)getuid(), (int)geteuid())); - smb_panic("failed to set gid\n"); - exit(1); + if (!non_root_mode()) { + DEBUG(0,("Failed to set gid privileges to (%d,%d) now set to (%d,%d) uid=(%d,%d)\n", + (int)rgid, (int)egid, + (int)getgid(), (int)getegid(), + (int)getuid(), (int)geteuid())); + smb_panic("failed to set gid\n"); + exit(1); + } } } diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c index e888c1cbcbf..70341507cb7 100644 --- a/source/lib/util_sid.c +++ b/source/lib/util_sid.c @@ -86,22 +86,16 @@ static known_sid_users builtin_groups[] = { { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" }, { 0, (enum SID_NAME_USE)0, NULL}}; +#define MAX_SID_NAMES 7 + static struct sid_name_map_info { DOM_SID *sid; char *name; known_sid_users *known_users; -} -sid_name_map[] = -{ - { &global_sam_sid, global_myname, NULL}, - { &global_sam_sid, global_myworkgroup, NULL}, - { &global_sid_Builtin, "BUILTIN", &builtin_groups[0]}, - { &global_sid_World_Domain, "", &everyone_users[0] }, - { &global_sid_Creator_Owner_Domain, "", &creator_owner_users[0] }, - { &global_sid_NT_Authority, "NT Authority", &nt_authority_users[0] }, - { NULL, NULL, NULL} -}; +} sid_name_map[MAX_SID_NAMES]; + +static BOOL sid_name_map_initialized = False; /* * An NT compatible anonymous token. @@ -114,6 +108,65 @@ NT_USER_TOKEN anonymous_token = { anon_sid_array }; +/************************************************************************** + quick init function + *************************************************************************/ +static void init_sid_name_map (void) +{ + int i = 0; + + if (sid_name_map_initialized) return; + + + if ((lp_security() == SEC_USER) && lp_domain_logons()) { + sid_name_map[i].sid = &global_sam_sid; + sid_name_map[i].name = global_myworkgroup; + sid_name_map[i].known_users = NULL; + i++; + sid_name_map[i].sid = &global_sam_sid; + sid_name_map[i].name = global_myname; + sid_name_map[i].known_users = NULL; + i++; + } + else { + sid_name_map[i].sid = &global_sam_sid; + sid_name_map[i].name = global_myname; + sid_name_map[i].known_users = NULL; + i++; + } + + sid_name_map[i].sid = &global_sid_Builtin; + sid_name_map[i].name = "BUILTIN"; + sid_name_map[i].known_users = &builtin_groups[0]; + i++; + + sid_name_map[i].sid = &global_sid_World_Domain; + sid_name_map[i].name = ""; + sid_name_map[i].known_users = &everyone_users[0]; + i++; + + sid_name_map[i].sid = &global_sid_Creator_Owner_Domain; + sid_name_map[i].name = ""; + sid_name_map[i].known_users = &creator_owner_users[0]; + i++; + + sid_name_map[i].sid = &global_sid_NT_Authority; + sid_name_map[i].name = "NT Authority"; + sid_name_map[i].known_users = &nt_authority_users[0]; + i++; + + + /* end of array */ + sid_name_map[i].sid = NULL; + sid_name_map[i].name = NULL; + sid_name_map[i].known_users = NULL; + + sid_name_map_initialized = True; + + return; + +} + /**************************************************************************** Creates some useful well known sids ****************************************************************************/ @@ -146,8 +199,12 @@ BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain) { fstring sid_str; int i = 0; + sid_to_string(sid_str, sid); + if (!sid_name_map_initialized) + init_sid_name_map(); + DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str)); if (nt_domain == NULL) @@ -156,7 +213,7 @@ BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain) while (sid_name_map[i].sid != NULL) { sid_to_string(sid_str, sid_name_map[i].sid); DEBUG(5,("map_domain_sid_to_name: compare: %s\n", sid_str)); - if (sid_equal(sid_name_map[i].sid, sid)) { + if (sid_equal(sid_name_map[i].sid, sid)) { fstrcpy(nt_domain, sid_name_map[i].name); DEBUG(5,("map_domain_sid_to_name: found '%s'\n", nt_domain)); return True; @@ -178,6 +235,9 @@ BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *p int i = 0; struct sid_name_map_info *psnm; + if (!sid_name_map_initialized) + init_sid_name_map(); + for(i = 0; sid_name_map[i].sid != NULL; i++) { psnm = &sid_name_map[i]; if(sid_equal(psnm->sid, sid)) { @@ -217,10 +277,13 @@ BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain) DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", nt_domain)); sid_copy(sid, &global_sam_sid); return True; - } + } DEBUG(5,("map_domain_name_to_sid: %s\n", nt_domain)); + if (!sid_name_map_initialized) + init_sid_name_map(); + while (sid_name_map[i].name != NULL) { DEBUG(5,("map_domain_name_to_sid: compare: %s\n", sid_name_map[i].name)); if (strequal(sid_name_map[i].name, nt_domain)) { @@ -382,6 +445,19 @@ BOOL sid_split_rid(DOM_SID *sid, uint32 *rid) } /***************************************************************** + Return the last rid from the end of a sid +*****************************************************************/ + +BOOL sid_peek_rid(DOM_SID *sid, uint32 *rid) +{ + if (sid->num_auths > 0) { + *rid = sid->sub_auths[sid->num_auths - 1]; + return True; + } + return False; +} + +/***************************************************************** Copies a sid *****************************************************************/ diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index 88fe8189b0d..bc693fd471b 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -106,9 +106,9 @@ static void print_socket_options(int s) for (; p->name != NULL; p++) { if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) { - DEBUG(3,("Could not test socket option %s.\n", p->name)); + DEBUG(5,("Could not test socket option %s.\n", p->name)); } else { - DEBUG(3,("socket option %s = %d\n",p->name,value)); + DEBUG(5,("socket option %s = %d\n",p->name,value)); } } } @@ -174,26 +174,25 @@ void set_socket_options(int fd, char *options) ssize_t read_udp_socket(int fd,char *buf,size_t len) { - ssize_t ret; - struct sockaddr_in sock; - int socklen; - - socklen = sizeof(sock); - memset((char *)&sock,'\0',socklen); - memset((char *)&lastip,'\0',sizeof(lastip)); - ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); - if (ret <= 0) { - DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); - return(0); - } + ssize_t ret; + struct sockaddr_in sock; + socklen_t socklen = sizeof(sock); + + memset((char *)&sock,'\0',socklen); + memset((char *)&lastip,'\0',sizeof(lastip)); + ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); + if (ret <= 0) { + DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); + return(0); + } - lastip = sock.sin_addr; - lastport = ntohs(sock.sin_port); + lastip = sock.sin_addr; + lastport = ntohs(sock.sin_port); - DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", - inet_ntoa(lastip), lastport, ret)); + DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", + inet_ntoa(lastip), lastport, ret)); - return(ret); + return(ret); } /**************************************************************************** @@ -642,35 +641,40 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) BOOL receive_smb(int fd,char *buffer, unsigned int timeout) { - ssize_t len,ret; + ssize_t len,ret; - smb_read_error = 0; + smb_read_error = 0; - memset(buffer,'\0',smb_size + 100); + memset(buffer,'\0',smb_size + 100); - len = read_smb_length_return_keepalive(fd,buffer,timeout); - if (len < 0) - { - DEBUG(10,("receive_smb: length < 0!\n")); - return(False); - } + len = read_smb_length_return_keepalive(fd,buffer,timeout); + if (len < 0) { + DEBUG(10,("receive_smb: length < 0!\n")); + return(False); + } - if (len > BUFFER_SIZE) { - DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); - if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) - { - exit(1); - } - } + /* + * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes + * of header. Don't print the error if this fits.... JRA. + */ - if(len > 0) { - ret = read_socket_data(fd,buffer+4,len); - if (ret != len) { - smb_read_error = READ_ERROR; - return False; - } - } - return(True); + if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { + DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); + if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { + smb_read_error = READ_ERROR; + return False; + } + } + + if(len > 0) { + ret = read_socket_data(fd,buffer+4,len); + if (ret != len) { + smb_read_error = READ_ERROR; + return False; + } + } + + return(True); } /**************************************************************************** @@ -708,55 +712,27 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) } /**************************************************************************** - send an null session message to a fd -****************************************************************************/ - -BOOL send_null_session_msg(int fd) -{ - ssize_t ret; - uint32 blank = 0; - size_t len = 4; - size_t nwritten=0; - char *buffer = (char *)␣ - - while (nwritten < len) - { - ret = write_socket(fd,buffer+nwritten,len - nwritten); - if (ret <= 0) - { - DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - exit(1); - } - nwritten += ret; - } - - DEBUG(10,("send_null_session_msg: sent 4 null bytes to client.\n")); - return True; -} - -/**************************************************************************** send an smb to a fd ****************************************************************************/ BOOL send_smb(int fd,char *buffer) { - size_t len; - size_t nwritten=0; - ssize_t ret; - len = smb_len(buffer) + 4; - - while (nwritten < len) - { - ret = write_socket(fd,buffer+nwritten,len - nwritten); - if (ret <= 0) - { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - exit(1); - } - nwritten += ret; - } + size_t len; + size_t nwritten=0; + ssize_t ret; + len = smb_len(buffer) + 4; + + while (nwritten < len) { + ret = write_socket(fd,buffer+nwritten,len - nwritten); + if (ret <= 0) { + DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", + (int)len,(int)ret, strerror(errno) )); + return False; + } + nwritten += ret; + } - return True; + return True; } /**************************************************************************** @@ -814,9 +790,9 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin { DEBUG(0,("gethostname failed\n")); return -1; } /* get host info */ - if ((hp = Get_Hostbyname(host_name)) == 0) + if ((hp = sys_gethostbyname(host_name)) == 0) { - DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name)); + DEBUG(0,( "sys_gethostbyname: Unknown host %s\n",host_name)); return -1; } @@ -939,27 +915,6 @@ connect_again: return res; } - -/******************************************************************* - Reset the 'done' variables so after a client process is created - from a fork call these calls will be re-done. This should be - expanded if more variables need reseting. - ******************************************************************/ - - -void reset_globals_after_fork(void) -{ - /* - * Re-seed the random crypto generator, so all smbd's - * started from the same parent won't generate the same - * sequence. - */ - { - unsigned char dummy; - generate_random_buffer( &dummy, 1, True); - } -} - /* the following 3 client_*() functions are nasty ways of allowing some generic functions to get info that really should be hidden in particular modules */ @@ -989,8 +944,8 @@ static BOOL matchname(char *remotehost,struct in_addr addr) struct hostent *hp; int i; - if ((hp = Get_Hostbyname(remotehost)) == 0) { - DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost)); + if ((hp = sys_gethostbyname(remotehost)) == 0) { + DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost)); return False; } @@ -1061,6 +1016,12 @@ char *get_socket_name(int fd) pstrcpy(name_buf,"UNKNOWN"); } } + + alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf)); + if (strstr(name_buf,"..")) { + pstrcpy(name_buf, "UNKNOWN"); + } + return name_buf; } @@ -1189,3 +1150,97 @@ int create_pipe_socket(char *dir, int dir_perms, return s; } + +/******************************************************************* +this is like socketpair but uses tcp. It is used by the Samba +regression test code +The function guarantees that nobody else can attach to the socket, +or if they do that this function fails and the socket gets closed +returns 0 on success, -1 on failure +the resulting file descriptors are symmetrical + ******************************************************************/ +static int socketpair_tcp(int fd[2]) +{ + int listener; + struct sockaddr_in sock; + struct sockaddr_in sock2; + socklen_t socklen = sizeof(sock); + int connect_done = 0; + + fd[0] = fd[1] = listener = -1; + + memset(&sock, 0, sizeof(sock)); + + if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; + + memset(&sock2, 0, sizeof(sock2)); +#ifdef HAVE_SOCK_SIN_LEN + sock2.sin_len = sizeof(sock2); +#endif + sock2.sin_family = PF_INET; + + bind(listener, (struct sockaddr *)&sock2, sizeof(sock2)); + + if (listen(listener, 1) != 0) goto failed; + + if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed; + + if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; + + set_blocking(fd[1], 0); + + sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) { + if (errno != EINPROGRESS) goto failed; + } else { + connect_done = 1; + } + + if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed; + + close(listener); + if (connect_done == 0) { + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0 + && errno != EISCONN) goto failed; + } + + set_blocking(fd[1], 1); + + /* all OK! */ + return 0; + + failed: + if (fd[0] != -1) close(fd[0]); + if (fd[1] != -1) close(fd[1]); + if (listener != -1) close(listener); + return -1; +} + + +/******************************************************************* +run a program on a local tcp socket, this is used to launch smbd +when regression testing +the return value is a socket which is attached to a subprocess +running "prog". stdin and stdout are attached. stderr is left +attached to the original stderr + ******************************************************************/ +int sock_exec(const char *prog) +{ + int fd[2]; + if (socketpair_tcp(fd) != 0) { + DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno))); + return -1; + } + if (fork() == 0) { + close(fd[0]); + close(0); + close(1); + dup(fd[1]); + dup(fd[1]); + exit(system(prog)); + } + close(fd[1]); + return fd[0]; +} + diff --git a/source/lib/util_str.c b/source/lib/util_str.c index 8ec319c3b84..07c91805cc7 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -545,9 +545,11 @@ BOOL trim_string(char *s,const char *front,const char *back) size_t back_len; char *sP; - if ( !s ) { + /* Ignore null or empty strings. */ + + if ( !s || (s[0] == '\0')) return False; - } + sP = s; s_len = strlen( s ) + 1; front_len = (front) ? strlen( front ) + 1 : 0; @@ -589,7 +591,7 @@ BOOL trim_string(char *s,const char *front,const char *back) * Kenichi Okuyama. */ - if ( back && back_len > 1 ) { + if ( back && back_len > 1 && s_len >= back_len) { char *bP = sP + s_len - back_len; long b_len = s_len; diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c index 71d900a3b33..9b3e25dd7ea 100644 --- a/source/lib/util_unistr.c +++ b/source/lib/util_unistr.c @@ -201,11 +201,10 @@ char *dos_unistr2_to_str(UNISTR2 *str) char *lbuf = lbufs[nexti]; char *p; uint16 *src = str->buffer; - int max_size = MIN(MAXUNI-3, str->uni_str_len); nexti = (nexti+1)%8; - for (p = lbuf; (p-lbuf < max_size) && *src; src++) { + for (p = lbuf; (p - lbuf < MAXUNI-3) && (src - str->buffer < str->uni_str_len) && *src; src++) { uint16 ucs2_val = SVAL(src,0); uint16 cp_val = ucs2_to_doscp[ucs2_val]; @@ -227,49 +226,41 @@ char *dos_unistr2_to_str(UNISTR2 *str) ********************************************************************/ void ascii_to_unistr(uint16 *dest, const char *src, int maxlen) { - uint16 *destend = dest + maxlen; - register char c; + uint16 *destend = dest + maxlen; + char c; - while (dest < destend) - { - c = *(src++); - if (c == 0) - { - break; - } + while (dest < destend) { + c = *(src++); + if (c == 0) + break; SSVAL(dest, 0, c); - dest++; - } + dest++; + } - *dest = 0; + *dest = 0; } - /******************************************************************* Pull an ASCII string out of a UNICODE array (uint16's). ********************************************************************/ void unistr_to_ascii(char *dest, const uint16 *src, int len) { - char *destend = dest + len; - register uint16 c; + char *destend = dest + len; + uint16 c; - if (src == NULL) - { + if (src == NULL) { *dest = '\0'; return; } /* normal code path for a valid 'src' */ - while (dest < destend) - { + while (dest < destend) { c = SVAL(src, 0); src++; if (c == 0) - { break; - } *(dest++) = (char)c; } @@ -339,11 +330,10 @@ char *dos_buffer2_to_str(BUFFER2 *str) char *lbuf = lbufs[nexti]; char *p; uint16 *src = str->buffer; - int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2); nexti = (nexti+1)%8; - for (p = lbuf; (p-lbuf < max_size) && *src; src++) { + for (p = lbuf; (p - lbuf < sizeof(str->buffer)-3) && (src - str->buffer < str->buf_len/2) && *src; src++) { uint16 ucs2_val = SVAL(src,0); uint16 cp_val = ucs2_to_doscp[ucs2_val]; @@ -368,11 +358,10 @@ char *dos_buffer2_to_multistr(BUFFER2 *str) char *lbuf = lbufs[nexti]; char *p; uint16 *src = str->buffer; - int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2); nexti = (nexti+1)%8; - for (p = lbuf; p-lbuf < max_size; src++) { + for (p = lbuf; (p - lbuf < sizeof(str->buffer)-3) && (src - str->buffer < str->buf_len/2); src++) { if (*src == 0) { *p++ = ' '; } else { @@ -481,8 +470,6 @@ int unistrcpy(char *dst, char *src) return num_wchars; } - - /******************************************************************* Free any existing maps. ********************************************************************/ @@ -505,7 +492,6 @@ static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp) } } - /******************************************************************* Build a default (null) codepage to unicode map. ********************************************************************/ diff --git a/source/libsmb/cli_lsarpc.c b/source/libsmb/cli_lsarpc.c index 7f5431e4b3a..88f0dff225b 100644 --- a/source/libsmb/cli_lsarpc.c +++ b/source/libsmb/cli_lsarpc.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 2.2 RPC pipe client - Copyright (C) Tim Potter 2000, + Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, @@ -84,8 +84,8 @@ void cli_lsa_shutdown(struct cli_state *cli) /* Open a LSA policy handle */ -uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, - uint32 des_access, POLICY_HND *pol) +uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL sec_qos, uint32 des_access, POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_OPEN_POL q; @@ -98,8 +98,8 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -140,7 +140,8 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, /* Close a LSA policy handle */ -uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) +uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_CLOSE q; @@ -152,8 +153,8 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -187,9 +188,9 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) /* Lookup a list of sids */ -uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, - int num_sids, DOM_SID *sids, char ***names, - uint32 **types, int *num_names) +uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_sids, DOM_SID *sids, + char ***names, uint32 **types, int *num_names) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -204,12 +205,12 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ - init_q_lookup_sids(cli->mem_ctx, &q, pol, num_sids, sids, 1); + init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1); if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { @@ -246,14 +247,14 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, (*num_names) = r.names->num_entries; - if (!((*names) = (char **)malloc(sizeof(char *) * + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.names->num_entries))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types) = (uint32 *)malloc(sizeof(uint32) * + if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.names->num_entries))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; @@ -277,7 +278,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, "%s%s%s", dom_name, dom_name[0] ? "\\" : "", name); - (*names)[i] = strdup(full_name); + (*names)[i] = talloc_strdup(mem_ctx, full_name); (*types)[i] = t_names.name[i].sid_name_use; } else { (*names)[i] = NULL; @@ -294,9 +295,9 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, /* Lookup a list of names */ -uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, - int num_names, char **names, DOM_SID **sids, - uint32 **types, int *num_sids) +uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_names, char **names, + DOM_SID **sids, uint32 **types, int *num_sids) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_NAMES q; @@ -310,12 +311,12 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ - init_q_lookup_names(cli->mem_ctx, &q, pol, num_names, names); + init_q_lookup_names(mem_ctx, &q, pol, num_names, names); if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { @@ -349,14 +350,14 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, (*num_sids) = r.num_entries; - if (!((*sids = (DOM_SID *)malloc(sizeof(DOM_SID) * + if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.num_entries)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types = (uint32 *)malloc(sizeof(uint32) * + if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.num_entries)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; @@ -395,9 +396,9 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, /* Query info policy */ -uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, - uint16 info_class, fstring domain_name, - DOM_SID * domain_sid) +uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint16 info_class, + fstring domain_name, DOM_SID *domain_sid) { prs_struct qbuf, rbuf; LSA_Q_QUERY_INFO q; @@ -409,8 +410,8 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -435,6 +436,9 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, /* Return output parameters */ + ZERO_STRUCTP(domain_sid); + domain_name[0] = '\0'; + switch (info_class) { case 3: @@ -479,9 +483,10 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, /* Enumerate list of trusted domains */ -uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, - uint32 *enum_ctx, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids) +uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *enum_ctx, + uint32 *num_domains, char ***domain_names, + DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -494,8 +499,8 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -516,7 +521,12 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, result = r.status; - if (result != NT_STATUS_NOPROBLEMO && result != 0x8000001a) { + /* For some undocumented reason this function sometimes returns + 0x8000001a (NT_STATUS_UNABLE_TO_FREE_VM) so we ignore it and + pretend everything is OK. */ + + if (result != NT_STATUS_NOPROBLEMO && + result != NT_STATUS_UNABLE_TO_FREE_VM) { /* An actual error ocured */ @@ -527,33 +537,42 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, /* Return output parameters */ - if (!((*domain_names) = (char **)malloc(sizeof(char *) * - r.num_domains))) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (r.num_domains) { - if (!((*domain_sids) = (DOM_SID *)malloc(sizeof(DOM_SID) * - r.num_domains))) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + /* Allocate memory for trusted domain names and sids */ - for (i = 0; i < r.num_domains; i++) { - fstring tmp; + *domain_names = (char **)talloc(mem_ctx, sizeof(char *) * + r.num_domains); - unistr2_to_ascii(tmp, &r.uni_domain_name[i], sizeof(tmp) - 1); - (*domain_names)[i] = strdup(tmp); - sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); + if (!*domain_names) { + DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + *domain_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * + r.num_domains); + if (!domain_sids) { + DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Copy across names and sids */ + + for (i = 0; i < r.num_domains; i++) { + fstring tmp; + + unistr2_to_ascii(tmp, &r.uni_domain_name[i], + sizeof(tmp) - 1); + (*domain_names)[i] = strdup(tmp); + sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); + } } *num_domains = r.num_domains; *enum_ctx = r.enum_context; - lsa_free_r_enum_trust_dom(&r); - done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); diff --git a/source/libsmb/cli_samr.c b/source/libsmb/cli_samr.c index 4c53bd05847..9fb7e078f67 100644 --- a/source/libsmb/cli_samr.c +++ b/source/libsmb/cli_samr.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 2.2 RPC pipe client - Copyright (C) Tim Potter 2000, + Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, @@ -84,21 +84,22 @@ void cli_samr_shutdown(struct cli_state *cli) /* Connect to SAMR database */ -uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, - uint32 access_mask, POLICY_HND *connect_pol) +uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *srv_name, uint32 access_mask, + POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CONNECT q; SAMR_R_CONNECT r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -106,14 +107,12 @@ uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, if (!samr_io_q_connect("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_connect("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -132,20 +131,21 @@ uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, /* Close SAMR handle */ -uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) +uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CLOSE_HND q; SAMR_R_CLOSE_HND r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -153,14 +153,12 @@ uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -179,22 +177,22 @@ uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) /* Open handle on a domain */ -uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, - uint32 access_mask, DOM_SID *domain_sid, - POLICY_HND *domain_pol) +uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol, uint32 access_mask, + DOM_SID *domain_sid, POLICY_HND *domain_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_DOMAIN q; SAMR_R_OPEN_DOMAIN r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -202,14 +200,12 @@ uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, if (!samr_io_q_open_domain("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_domain("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -228,22 +224,22 @@ uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, /* Open handle on a user */ -uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, - uint32 access_mask, uint32 user_rid, - POLICY_HND *user_pol) +uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 user_rid, POLICY_HND *user_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_USER q; SAMR_R_OPEN_USER r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -251,14 +247,12 @@ uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, if (!samr_io_q_open_user("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_user("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -277,22 +271,22 @@ uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, /* Open handle on a group */ -uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, - uint32 access_mask, uint32 group_rid, - POLICY_HND *group_pol) +uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 group_rid, POLICY_HND *group_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_GROUP q; SAMR_R_OPEN_GROUP r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -300,14 +294,12 @@ uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, if (!samr_io_q_open_group("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_group("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -326,21 +318,22 @@ uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, /* Query user info */ -uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, - uint16 switch_value, SAM_USERINFO_CTR *ctr) +uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERINFO q; SAMR_R_QUERY_USERINFO r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -348,7 +341,6 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -357,7 +349,6 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, r.ctr = ctr; if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -374,21 +365,22 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, /* Query group info */ -uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, - uint32 info_level, GROUP_INFO_CTR *ctr) +uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 info_level, + GROUP_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPINFO q; SAMR_R_QUERY_GROUPINFO r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -396,7 +388,6 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -405,7 +396,6 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, r.ctr = ctr; if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -422,21 +412,22 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, /* Query user groups */ -uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, - uint32 *num_groups, DOM_GID **gid) +uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint32 *num_groups, + DOM_GID **gid) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERGROUPS q; SAMR_R_QUERY_USERGROUPS r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -444,14 +435,12 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -471,21 +460,22 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, /* Query user groups */ -uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, - uint32 *num_mem, uint32 **rid, uint32 **attr) +uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 *num_mem, + uint32 **rid, uint32 **attr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPMEM q; SAMR_R_QUERY_GROUPMEM r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -493,14 +483,12 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -518,3 +506,288 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, return result; } + +/* Enumerate domain groups */ + +uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *start_idx, + uint32 size, struct acct_info **dom_groups, + uint32 *num_dom_groups) +{ + prs_struct qbuf, rbuf; + SAMR_Q_ENUM_DOM_GROUPS q; + SAMR_R_ENUM_DOM_GROUPS r; + uint32 result = NT_STATUS_UNSUCCESSFUL, name_idx, i; + + 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_samr_q_enum_dom_groups(&q, pol, *start_idx, size); + + if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + result = r.status; + + if (result != NT_STATUS_NOPROBLEMO && + result != STATUS_MORE_ENTRIES) { + goto done; + } + + *num_dom_groups = r.num_entries2; + + if (!((*dom_groups) = (struct acct_info *) + talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); + + name_idx = 0; + + for (i = 0; i < *num_dom_groups; i++) { + + (*dom_groups)[i].rid = r.sam[i].rid; + + if (r.sam[i].hdr_name.buffer) { + unistr2_to_ascii((*dom_groups)[i].acct_name, + &r.uni_grp_name[name_idx], + sizeof(fstring) - 1); + name_idx++; + } + + *start_idx = r.next_idx; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query alias members */ + +uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *alias_pol, uint32 *num_mem, + DOM_SID **sids) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_ALIASMEM q; + SAMR_R_QUERY_ALIASMEM r; + uint32 result = NT_STATUS_UNSUCCESSFUL, i; + + 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_samr_q_query_aliasmem(&q, alias_pol); + + if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + *num_mem = r.num_sids; + + if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i = 0; i < *num_mem; i++) { + (*sids)[i] = r.sid[i].sid; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Open handle on an alias */ + +uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 alias_rid, POLICY_HND *alias_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_OPEN_ALIAS q; + SAMR_R_OPEN_ALIAS r; + uint32 result; + + 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_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid); + + if (!samr_io_q_open_alias("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_open_alias("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *alias_pol = r.pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query domain info */ + +uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint16 switch_value, + SAM_UNK_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_DOMAIN_INFO q; + SAMR_R_QUERY_DOMAIN_INFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + 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_samr_q_query_dom_info(&q, domain_pol, switch_value); + + if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + r.ctr = ctr; + + if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query display info */ + +uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 *start_idx, + uint16 switch_value, uint32 *num_entries, + uint32 max_entries, SAM_DISPINFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_DISPINFO q; + SAMR_R_QUERY_DISPINFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + 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_samr_q_query_dispinfo(&q, domain_pol, switch_value, + *start_idx, max_entries); + + if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + *num_entries = r.num_entries; + *start_idx += r.num_entries; /* No next_idx in this structure! */ + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} diff --git a/source/libsmb/cli_spoolss.c b/source/libsmb/cli_spoolss.c index db761e57bfa..2c962ef27a0 100644 --- a/source/libsmb/cli_spoolss.c +++ b/source/libsmb/cli_spoolss.c @@ -87,10 +87,16 @@ void cli_spoolss_shutdown(struct cli_state *cli) /* Open printer ex */ -uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, - char *datatype, uint32 access_required, - char *station, char *username, - POLICY_HND *pol) +uint32 cli_spoolss_open_printer_ex( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *printername, + char *datatype, + uint32 access_required, + char *station, + char *username, + POLICY_HND *pol +) { prs_struct qbuf, rbuf; SPOOL_Q_OPEN_PRINTER_EX q; @@ -102,8 +108,8 @@ uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -140,7 +146,11 @@ uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, /* Close a printer handle */ -uint32 cli_spoolss_close_printer(struct cli_state *cli, POLICY_HND *pol) +uint32 cli_spoolss_close_printer( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol +) { prs_struct qbuf, rbuf; SPOOL_Q_CLOSEPRINTER q; @@ -152,8 +162,8 @@ uint32 cli_spoolss_close_printer(struct cli_state *cli, POLICY_HND *pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -201,8 +211,12 @@ static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) /* Decode various printer info levels - perhaps this should live in parse_spoolss.c? */ -static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_0 **info) +static void decode_printer_info_0( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_0 **info +) { uint32 i; PRINTER_INFO_0 *inf; @@ -218,13 +232,17 @@ static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_1 **info) +static void decode_printer_info_1( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_1 **info +) { uint32 i; PRINTER_INFO_1 *inf; - inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1)); + inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1)); buffer->prs.data_offset=0; @@ -235,13 +253,17 @@ static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_2 **info) +static void decode_printer_info_2( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_2 **info +) { uint32 i; PRINTER_INFO_2 *inf; - inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2)); + inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2)); buffer->prs.data_offset=0; @@ -254,13 +276,17 @@ static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_3 **info) +static void decode_printer_info_3( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_3 **info +) { uint32 i; PRINTER_INFO_3 *inf; - inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3)); + inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3)); buffer->prs.data_offset=0; @@ -275,13 +301,17 @@ static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned, /********************************************************************** Decode a PORT_INFO_1 struct from a NEW_BUFFER **********************************************************************/ -static void decode_port_info_1(NEW_BUFFER *buffer, uint32 returned, - PORT_INFO_1 **info) +static void decode_port_info_1( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PORT_INFO_1 **info +) { uint32 i; PORT_INFO_1 *inf; - inf=(PORT_INFO_1*)malloc(returned*sizeof(PORT_INFO_1)); + inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1)); prs_set_offset(&buffer->prs, 0); @@ -295,13 +325,16 @@ static void decode_port_info_1(NEW_BUFFER *buffer, uint32 returned, /********************************************************************** Decode a PORT_INFO_2 struct from a NEW_BUFFER **********************************************************************/ -static void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned, - PORT_INFO_2 **info) +static void decode_port_info_2( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PORT_INFO_2 **info) { uint32 i; PORT_INFO_2 *inf; - inf=(PORT_INFO_2*)malloc(returned*sizeof(PORT_INFO_2)); + inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2)); prs_set_offset(&buffer->prs, 0); @@ -312,13 +345,17 @@ static void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, - DRIVER_INFO_1 **info) +static void decode_printer_driver_1( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + DRIVER_INFO_1 **info +) { uint32 i; DRIVER_INFO_1 *inf; - inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1)); + inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1)); buffer->prs.data_offset=0; @@ -329,13 +366,17 @@ static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, - DRIVER_INFO_2 **info) +static void decode_printer_driver_2( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + DRIVER_INFO_2 **info +) { uint32 i; DRIVER_INFO_2 *inf; - inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2)); + inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2)); buffer->prs.data_offset=0; @@ -347,6 +388,7 @@ static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, } static void decode_printer_driver_3( + TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_3 **info @@ -355,7 +397,7 @@ static void decode_printer_driver_3( uint32 i; DRIVER_INFO_3 *inf; - inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3)); + inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3)); buffer->prs.data_offset=0; @@ -367,6 +409,7 @@ static void decode_printer_driver_3( } static void decode_printerdriverdir_1 ( + TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, uint32 returned, DRIVER_DIRECTORY_1 **info @@ -374,7 +417,7 @@ static void decode_printerdriverdir_1 ( { DRIVER_DIRECTORY_1 *inf; - inf=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1)); + inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1)); prs_set_offset(&buffer->prs, 0); @@ -386,9 +429,14 @@ static void decode_printerdriverdir_1 ( /* Enumerate printers */ -uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, - uint32 level, int *returned, - PRINTER_INFO_CTR *ctr) +uint32 cli_spoolss_enum_printers( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 flags, + uint32 level, + int *returned, + PRINTER_INFO_CTR *ctr +) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPRINTERS q; @@ -407,10 +455,10 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, needed); @@ -430,21 +478,20 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO && r.returned > 0) { - - *returned = r.returned; + if (((result=r.status) == NT_STATUS_NOPROBLEMO) && (*returned = r.returned)) + { switch (level) { case 1: - decode_printer_info_1(r.buffer, r.returned, + decode_printer_info_1(mem_ctx, r.buffer, r.returned, &ctr->printers_1); break; case 2: - decode_printer_info_2(r.buffer, r.returned, + decode_printer_info_2(mem_ctx, r.buffer, r.returned, &ctr->printers_2); break; case 3: - decode_printer_info_3(r.buffer, r.returned, + decode_printer_info_3(mem_ctx, r.buffer, r.returned, &ctr->printers_3); break; } @@ -460,8 +507,13 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, } /* Enumerate printer ports */ -uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, - int *returned, PORT_INFO_CTR *ctr) +uint32 cli_spoolss_enum_ports( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 level, + int *returned, + PORT_INFO_CTR *ctr +) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPORTS q; @@ -480,10 +532,10 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); make_spoolss_q_enumports(&q, server, level, &buffer, needed); @@ -509,11 +561,11 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, switch (level) { case 1: - decode_port_info_1(r.buffer, r.returned, + decode_port_info_1(mem_ctx, r.buffer, r.returned, &ctr->port.info_1); break; case 2: - decode_port_info_2(r.buffer, r.returned, + decode_port_info_2(mem_ctx, r.buffer, r.returned, &ctr->port.info_2); break; } @@ -531,6 +583,7 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, /* Get printer info */ uint32 cli_spoolss_getprinter( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr @@ -549,12 +602,12 @@ uint32 cli_spoolss_getprinter( do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_getprinter(&q, pol, level, &buffer, needed); + make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, needed); /* Marshall data and send request */ if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || @@ -574,16 +627,16 @@ uint32 cli_spoolss_getprinter( switch (level) { case 0: - decode_printer_info_0(r.buffer, 1, &ctr->printers_0); + decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); break; case 1: - decode_printer_info_1(r.buffer, 1, &ctr->printers_1); + decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1); break; case 2: - decode_printer_info_2(r.buffer, 1, &ctr->printers_2); + decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2); break; case 3: - decode_printer_info_3(r.buffer, 1, &ctr->printers_3); + decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3); break; } } @@ -602,6 +655,7 @@ uint32 cli_spoolss_getprinter( */ uint32 cli_spoolss_setprinter( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr, @@ -617,13 +671,12 @@ uint32 cli_spoolss_setprinter( ZERO_STRUCT(r); /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_setprinter(&q, pol, level, ctr, command); + make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) { @@ -632,7 +685,6 @@ uint32 cli_spoolss_setprinter( } /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) { goto done; @@ -653,6 +705,7 @@ done: */ uint32 cli_spoolss_getprinterdriver ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, char* env, @@ -677,10 +730,10 @@ uint32 cli_spoolss_getprinterdriver ( { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ @@ -707,13 +760,13 @@ uint32 cli_spoolss_getprinterdriver ( switch (level) { case 1: - decode_printer_driver_1(r.buffer, 1, &ctr->info1); + decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1); break; case 2: - decode_printer_driver_2(r.buffer, 1, &ctr->info2); + decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2); break; case 3: - decode_printer_driver_3(r.buffer, 1, &ctr->info3); + decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); break; } } @@ -732,6 +785,7 @@ uint32 cli_spoolss_getprinterdriver ( */ uint32 cli_spoolss_enumprinterdrivers ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, char* env, uint32 *returned, @@ -755,10 +809,10 @@ uint32 cli_spoolss_enumprinterdrivers ( do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ @@ -787,13 +841,13 @@ uint32 cli_spoolss_enumprinterdrivers ( switch (level) { case 1: - decode_printer_driver_1(r.buffer, r.returned, &ctr->info1); + decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1); break; case 2: - decode_printer_driver_2(r.buffer, r.returned, &ctr->info2); + decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2); break; case 3: - decode_printer_driver_3(r.buffer, r.returned, &ctr->info3); + decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); break; } } @@ -813,6 +867,7 @@ uint32 cli_spoolss_enumprinterdrivers ( */ uint32 cli_spoolss_getprinterdriverdir ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, char* env, DRIVER_DIRECTORY_CTR *ctr @@ -835,10 +890,10 @@ uint32 cli_spoolss_getprinterdriverdir ( do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ @@ -864,7 +919,7 @@ uint32 cli_spoolss_getprinterdriverdir ( switch (level) { case 1: - decode_printerdriverdir_1(r.buffer, 1, &ctr->info1); + decode_printerdriverdir_1(mem_ctx, r.buffer, 1, &ctr->info1); break; } } @@ -883,6 +938,7 @@ uint32 cli_spoolss_getprinterdriverdir ( */ uint32 cli_spoolss_addprinterdriver ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, PRINTER_DRIVER_CTR *ctr ) @@ -890,22 +946,22 @@ uint32 cli_spoolss_addprinterdriver ( prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTERDRIVER q; SPOOL_R_ADDPRINTERDRIVER r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); - + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ - make_spoolss_q_addprinterdriver (&q, server, level, ctr); + make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr); /* Marshall data and send request */ result = NT_STATUS_UNSUCCESSFUL; @@ -929,7 +985,7 @@ uint32 cli_spoolss_addprinterdriver ( done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - + return result; } @@ -938,6 +994,7 @@ done: */ uint32 cli_spoolss_addprinterex ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR *ctr ) @@ -961,12 +1018,12 @@ uint32 cli_spoolss_addprinterex ( /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ - make_spoolss_q_addprinterex (&q, server, client, user, level, ctr); + make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, level, ctr); /* Marshall data and send request */ result = NT_STATUS_UNSUCCESSFUL; @@ -994,4 +1051,61 @@ done: return result; } +/********************************************************************** + * Delete a Printer Driver from the server (does not remove + * the driver files + */ +uint32 cli_spoolss_deleteprinterdriver ( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *arch, + char *driver +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEPRINTERDRIVER q; + SPOOL_R_DELETEPRINTERDRIVER r; + uint32 result; + fstring server; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + + /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (server); + + /* write the request */ + make_spoolss_q_deleteprinterdriver (mem_ctx, &q, server, arch, driver); + + /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) + { + goto done; + } + + + /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) + { + goto done; + } + + /* Return output parameters */ + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c index 8a56a08b1d4..67eef52583f 100644 --- a/source/libsmb/cliconnect.c +++ b/source/libsmb/cliconnect.c @@ -104,8 +104,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* * Plaintext mode needed, assume plaintext supplied. */ - fstrcpy(pword, pass); - unix_to_dos(pword,True); + passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE); fstrcpy(ntpword, ""); ntpasslen = 0; } @@ -124,7 +123,7 @@ BOOL cli_session_setup(struct cli_state *cli, if (cli->protocol < PROTOCOL_NT1) { - set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); + set_message(cli->outbuf,10, 0, True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -137,12 +136,20 @@ BOOL cli_session_setup(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); + p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_UPPER|STR_TERMINATE); + cli_setup_bcc(cli, p); } else { + uint32 capabilities; + + capabilities = CAP_NT_SMBS; + if (cli->use_level_II_oplocks) { + capabilities |= CAP_LEVEL_II_OPLOCKS; + } + if (cli->capabilities & CAP_UNICODE) { + capabilities |= CAP_UNICODE; + } set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -154,23 +161,17 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,CAP_NT_SMBS|(cli->use_level_II_oplocks ? CAP_LEVEL_II_OPLOCKS : 0)); + SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpword,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,workgroup); - unix_to_dos(p,True); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,"Unix");p = skip_string(p,1); - pstrcpy(p,"Samba");p = skip_string(p,1); - set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, workgroup, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, "Unix", -1, STR_CONVERT|STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_CONVERT|STR_TERMINATE); + cli_setup_bcc(cli, p); } cli_send_smb(cli); @@ -187,24 +188,17 @@ BOOL cli_session_setup(struct cli_state *cli, cli->vuid = SVAL(cli->inbuf,smb_uid); if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *server_domain,*server_os,*server_type; - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); - fstrcpy(cli->server_os, server_os); - dos_to_unix(cli->server_os, True); - fstrcpy(cli->server_type, server_type); - dos_to_unix(cli->server_type, True); - fstrcpy(cli->server_domain, server_domain); - dos_to_unix(cli->server_domain, True); + /* + * Save off some of the connected server + * info. + */ + char *q = smb_buf(cli->inbuf); + q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); + q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); + q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); } fstrcpy(cli->user_name, user); - dos_to_unix(cli->user_name, True); return True; } @@ -257,12 +251,11 @@ BOOL cli_send_tconX(struct cli_state *cli, unix_to_dos(dos_pword,True); SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); } else { - if(!(cli->sec_mode & 2)) { + if((cli->sec_mode & 3) == 0) { /* * Non-encrypted passwords - convert to DOS codepage before using. */ - fstrcpy(pword,pass); - unix_to_dos(pword,True); + passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE); } else { memcpy(pword, pass, passlen); } @@ -273,8 +266,7 @@ BOOL cli_send_tconX(struct cli_state *cli, unix_to_dos(fullshare, True); strupper(fullshare); - set_message(cli->outbuf,4, - 2 + strlen(fullshare) + passlen + strlen(dev),True); + set_message(cli->outbuf,4, 0, True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -284,10 +276,10 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - fstrcpy(p,fullshare); - p = skip_string(p,1); - pstrcpy(p,dev); - unix_to_dos(p,True); + p += clistr_push(cli, p, fullshare, -1, STR_CONVERT | STR_TERMINATE); + fstrcpy(p, dev); p += strlen(dev)+1; + + cli_setup_bcc(cli, p); SCVAL(cli->inbuf,smb_rcls, 1); @@ -302,7 +294,7 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); if (cli->protocol >= PROTOCOL_NT1) { - fstrcpy(cli->dev, smb_buf(cli->inbuf)); + clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE | STR_CONVERT); } if (strcasecmp(share,"IPC$")==0) { @@ -347,17 +339,11 @@ void cli_negprot_send(struct cli_state *cli) { char *p; int numprots; - int plength; memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ - for (plength=0,numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) - plength += strlen(prots[numprots].name)+2; - - set_message(cli->outbuf,0,plength,True); + set_message(cli->outbuf,0,0,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -370,6 +356,7 @@ void cli_negprot_send(struct cli_state *cli) } CVAL(cli->outbuf,smb_com) = SMBnegprot; + cli_setup_bcc(cli, p); cli_setup_packet(cli); CVAL(smb_buf(cli->outbuf),0) = 2; @@ -442,6 +429,12 @@ BOOL cli_negprot(struct cli_state *cli) cli->readbraw_supported = True; cli->writebraw_supported = True; } + /* work out if they sent us a workgroup */ + if (smb_buflen(cli->inbuf) > 8) { + clistr_pull(cli, cli->server_domain, + smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), + smb_buflen(cli->inbuf)-8, STR_CONVERT|STR_UNICODE|STR_NOALIGN); + } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); @@ -461,6 +454,11 @@ BOOL cli_negprot(struct cli_state *cli) cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); + /* a way to force ascii SMB */ + if (getenv("CLI_FORCE_ASCII")) { + cli->capabilities &= ~CAP_UNICODE; + } + return True; } @@ -560,7 +558,6 @@ retry: return(True); } - /**************************************************************************** open the client sockets ****************************************************************************/ @@ -582,8 +579,12 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) if (cli->port == 0) cli->port = 139; /* Set to default */ - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli->port, cli->timeout); + if (getenv("LIBSMB_PROG")) { + cli->fd = sock_exec(getenv("LIBSMB_PROG")); + } else { + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + cli->port, cli->timeout); + } if (cli->fd == -1) return False; @@ -677,7 +678,7 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session request\n")); if (do_shutdown) - cli_shutdown(cli); + cli_shutdown(cli); return False; } diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 19380498063..8d4a025fcc0 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -106,11 +106,23 @@ void cli_setup_packet(struct cli_state *cli) SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); if (cli->protocol > PROTOCOL_CORE) { + uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,0x1); + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + if (cli->capabilities & CAP_UNICODE) { + flags2 |= FLAGS2_UNICODE_STRINGS; + } + SSVAL(cli->outbuf,smb_flg2, flags2); } } +/**************************************************************************** +setup the bcc length of the packet from a pointer to the end of the data +****************************************************************************/ +void cli_setup_bcc(struct cli_state *cli, void *p) +{ + set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); +} /**************************************************************************** diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c index eb2ca624e85..6d499867905 100644 --- a/source/libsmb/clierror.c +++ b/source/libsmb/clierror.c @@ -198,11 +198,12 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; case ERROR_INVALID_NAME: return ENOENT; + case ERRnosuchshare: return ENODEV; } } if (rcls == ERRSRV) { switch (code) { - case ERRbadpw: return EACCES; + case ERRbadpw: return EPERM; case ERRaccess: return EACCES; case ERRnoresource: return ENOMEM; case ERRinvdevice: return ENODEV; diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c index 63706f7669e..56d2f63c799 100644 --- a/source/libsmb/clifile.c +++ b/source/libsmb/clifile.c @@ -33,7 +33,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); + set_message(cli->outbuf,1, 0, True); CVAL(cli->outbuf,smb_com) = SMBmv; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -43,12 +43,13 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,fname_src); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, fname_src, -1, + STR_TERMINATE | STR_CONVERT); *p++ = 4; - pstrcpy(p,fname_dst); - unix_to_dos(p,True); + p += clistr_push(cli, p, fname_dst, -1, + STR_TERMINATE | STR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -72,7 +73,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 2 + strlen(fname),True); + set_message(cli->outbuf,1, 0,True); CVAL(cli->outbuf,smb_com) = SMBunlink; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -82,9 +83,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,fname); - unix_to_dos(p,True); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; @@ -107,7 +108,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 2 + strlen(dname),True); + set_message(cli->outbuf,0, 0,True); CVAL(cli->outbuf,smb_com) = SMBmkdir; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -115,8 +116,9 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); + p += clistr_push(cli, p, dname, -1, STR_CONVERT|STR_TERMINATE); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -140,7 +142,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 2 + strlen(dname),True); + set_message(cli->outbuf,0, 0, True); CVAL(cli->outbuf,smb_com) = SMBrmdir; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -148,8 +150,9 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); + p += clistr_push(cli, p, dname, -1, STR_TERMINATE|STR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -183,11 +186,11 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) data = flag ? 1 : 0; if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - &data, data_len, cli->max_xmit /* data, length, max */ + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + &data, data_len, cli->max_xmit /* data, length, max */ )) { return False; } @@ -209,15 +212,17 @@ 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, char *fname, uint32 DesiredAccess, uint32 FileAttributes, - uint32 ShareAccess, uint32 CreateDisposition, uint32 CreateOptions) +int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, + uint32 FileAttributes, uint32 ShareAccess, + uint32 CreateDisposition, uint32 CreateOptions) { char *p; + int len; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,24,1 + strlen(fname),True); + set_message(cli->outbuf,24,0,True); CVAL(cli->outbuf,smb_com) = SMBntcreateX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -235,12 +240,17 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition); SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions); SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); + /* this alignment and termination is critical for netapp filers. Don't change */ + p += clistr_align_out(cli, p, STR_CONVERT); + len = clistr_push(cli, p, fname, -1, STR_CONVERT); + p += len; + SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); + /* sigh. this copes with broken netapp filer behaviour */ + p += clistr_push(cli, p, "", -1, STR_TERMINATE); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -257,6 +267,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, /**************************************************************************** open a file ****************************************************************************/ + int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) { return cli_nt_create_full(cli, fname, DesiredAccess, 0, @@ -265,56 +276,6 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) /**************************************************************************** open a file -****************************************************************************/ -int cli_nt_create_uni(struct cli_state *cli, char *fname, uint32 DesiredAccess) -{ - pstring uni; - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,24,(strlen(fname) + 1) * 2 + 1,True); - - CVAL(cli->outbuf,smb_com) = SMBntcreateX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - 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); - SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); - SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); - SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); - SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname) * 2); - - p = smb_buf(cli->outbuf); - p++; /* Alignment */ - pstrcpy(uni, fname); - unix_to_dos(uni, True); - dos_struni2(p, uni, (strlen(fname) + 1) * 2); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2 + 1); -} - - -/**************************************************************************** -open a file WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) @@ -353,7 +314,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,15,1 + strlen(fname),True); + set_message(cli->outbuf,15,0,True); CVAL(cli->outbuf,smb_com) = SMBopenX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -375,9 +336,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) } p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -436,7 +397,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,10,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -453,6 +414,11 @@ BOOL cli_lock(struct cli_state *cli, int fnum, SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); + + p += 10; + + cli_setup_bcc(cli, p); + cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); @@ -481,7 +447,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,10,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -498,7 +464,8 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - + p += 10; + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; @@ -528,7 +495,7 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,20,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -543,8 +510,11 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, p = smb_buf(cli->outbuf); SIVAL(p, 0, cli->pid); - SOFF_T_R(p, 0, offset); + SOFF_T_R(p, 4, offset); SOFF_T_R(p, 12, len); + p += 20; + + cli_setup_bcc(cli, p); cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); @@ -573,7 +543,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,20,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -590,7 +560,8 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ SIVAL(p, 0, cli->pid); SOFF_T_R(p, 4, offset); SOFF_T_R(p, 12, len); - + p += 20; + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; @@ -669,16 +640,17 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0,strlen(fname)+2,True); + set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBgetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); + *p++ = 4; + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -716,7 +688,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,strlen(fname)+4,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBsetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -726,11 +698,11 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) put_dos_date3(cli->outbuf,smb_vwv1, t); p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); - p = skip_string(p,1); - *p = 4; + *p++ = 4; + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + *p++ = 4; + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -758,14 +730,15 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) if (!*path2) *path2 = '\\'; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,4 + strlen(path2),True); + set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBchkpth); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; - safe_strcpy(p,path2,strlen(path2)); - unix_to_dos(p,True); + p += clistr_push(cli, p, path2, -1, STR_TERMINATE | STR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -802,3 +775,44 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } + +/**************************************************************************** +create and open a temporary file +****************************************************************************/ +int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,1,strlen(path)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBctemp; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0); + + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, path, -1, STR_TERMINATE | STR_CONVERT); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + if (tmp_path) { + pstring path2; + clistr_pull(cli, path2, smb_buf(cli->inbuf)+1, + sizeof(path2), -1, STR_TERMINATE | STR_CONVERT); + *tmp_path = strdup(path2); + } + + return SVAL(cli->inbuf,smb_vwv0); +} diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c index 2e904e06b7d..a04c691fa49 100644 --- a/source/libsmb/clilist.c +++ b/source/libsmb/clilist.c @@ -30,7 +30,8 @@ The length of the structure is returned The structure of a long filename depends on the info level. 260 is used by NT and 2 is used by OS/2 ****************************************************************************/ -static int interpret_long_filename(int level,char *p,file_info *finfo) +static int interpret_long_filename(struct cli_state *cli, + int level,char *p,file_info *finfo) { extern file_info def_finfo; @@ -47,8 +48,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+27); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+27, + sizeof(finfo->name), + -1, + STR_TERMINATE | STR_CONVERT); } return(28 + CVAL(p,26)); @@ -60,8 +63,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+31); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+31, + sizeof(finfo->name), + -1, + STR_TERMINATE | STR_CONVERT); } return(32 + CVAL(p,30)); @@ -74,8 +79,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+33); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+33, + sizeof(finfo->name), + -1, + STR_TERMINATE | STR_CONVERT); } return(SVAL(p,4)+4); @@ -87,15 +94,17 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+37); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+37, + sizeof(finfo->name), + -1, + STR_TERMINATE | STR_CONVERT); } return(SVAL(p,4)+4); case 260: /* NT uses this, but also accepts 2 */ if (finfo) { int ret = SVAL(p,0); - int namelen, slen; + int namelen; p += 4; /* next entry offset */ p += 4; /* fileindex */ @@ -122,18 +131,21 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; p += 4; /* EA size */ - slen = SVAL(p, 0); + /* slen = SVAL(p, 0); */ p += 2; - if (p[1] == 0 && slen > 1) { - /* NT has stuffed up again */ - unistr_to_dos(finfo->short_name, p, slen/2); - } else { - strncpy(finfo->short_name, p, 12); - finfo->short_name[12] = 0; + { + /* stupid NT bugs. grr */ + int flags = STR_CONVERT; + if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; + clistr_pull(cli, finfo->short_name, p, + sizeof(finfo->short_name), + 24, flags); } p += 24; /* short name? */ - StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + namelen, + STR_CONVERT); return(ret); } return(SVAL(p,0)); @@ -147,12 +159,11 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) +int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state) { int max_matches = 512; - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - int info_level = cli->protocol<PROTOCOL_NT1?1:260; + int info_level; char *p, *p2; pstring mask; file_info finfo; @@ -170,9 +181,11 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int param_len, data_len; uint16 setup; pstring param; - + + /* NT uses 260, OS/2 uses 2. Both accept 1. */ + info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; + pstrcpy(mask,Mask); - unix_to_dos(mask,True); while (ff_eos == 0) { loop_count++; @@ -181,8 +194,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - param_len = 12+strlen(mask)+1; - if (First) { setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ @@ -190,7 +201,9 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,4+2); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); - pstrcpy(param+12,mask); + p = param+12; + p += clistr_push(cli, param+12, mask, -1, + STR_TERMINATE | STR_CONVERT); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -198,14 +211,15 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ - pstrcpy(param+12,mask); - - DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_lastname,mask)); + p = param+12; + p += clistr_push(cli, param+12, mask, -1, + STR_TERMINATE | STR_CONVERT); } + param_len = PTR_DIFF(p, param); + if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ + NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ @@ -254,19 +268,24 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, switch(info_level) { case 260: - StrnCpy(mask,p+ff_lastname, - MIN(sizeof(mask)-1,data_len-ff_lastname)); + clistr_pull(cli, mask, p+ff_lastname, + sizeof(mask), + data_len-ff_lastname, + STR_TERMINATE | + STR_CONVERT); break; case 1: - pstrcpy(mask,p + ff_lastname + 1); + clistr_pull(cli, mask, p+ff_lastname+1, + sizeof(mask), + -1, + STR_TERMINATE | + STR_CONVERT); break; } } else { pstrcpy(mask,""); } - dos_to_unix(mask, True); - /* and add them to the dirlist pool */ dirlist = Realloc(dirlist,dirlist_len + data_len); @@ -278,7 +297,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, /* put in a length for the last entry, to ensure we can chain entries into the next packet */ for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(info_level,p2,NULL); + p2 += interpret_long_filename(cli,info_level,p2,NULL); SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); /* grab the data for later use */ @@ -299,8 +318,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, } for (p=dirlist,i=0;i<total_received;i++) { - p += interpret_long_filename(info_level,p,&finfo); - fn(&finfo, Mask); + p += interpret_long_filename(cli,info_level,p,&finfo); + fn(&finfo, Mask, state); } /* free up the dirlist buffer */ @@ -314,7 +333,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, interpret a short filename structure The length of the structure is returned ****************************************************************************/ -static int interpret_short_filename(char *p,file_info *finfo) +static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { extern file_info def_finfo; @@ -326,7 +345,7 @@ static int interpret_short_filename(char *p,file_info *finfo) finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); - pstrcpy(finfo->name,p+30); + clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_CONVERT|STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); @@ -340,7 +359,7 @@ static int interpret_short_filename(char *p,file_info *finfo) but should otherwise not be used ****************************************************************************/ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) + void (*fn)(file_info *, const char *, void *), void *state) { char *p; int received = 0; @@ -360,12 +379,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if (first) - set_message(cli->outbuf,2,5 + strlen(mask),True); - else - set_message(cli->outbuf,2,5 + 21,True); + set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBffirst; + CVAL(cli->outbuf,smb_com) = SMBsearch; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -376,21 +392,19 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - if (first) - pstrcpy(p,mask); - else - pstrcpy(p,""); - p += strlen(p) + 1; - + p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE|STR_CONVERT); *p++ = 5; if (first) { SSVAL(p,0,0); + p += 2; } else { SSVAL(p,0,21); p += 2; memcpy(p,status,21); + p += 21; } + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) break; @@ -420,7 +434,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,5 + 21,True); + set_message(cli->outbuf,2,0,True); CVAL(cli->outbuf,smb_com) = SMBfclose; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -436,7 +450,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(p, 0, 21); p += 2; memcpy(p,status,21); + p += 21; + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); @@ -445,10 +461,24 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, for (p=dirlist,i=0;i<num_received;i++) { file_info finfo; - p += interpret_short_filename(p,&finfo); - fn(&finfo, Mask); + p += interpret_short_filename(cli, p,&finfo); + fn(&finfo, Mask, state); } if (dirlist) free(dirlist); return(num_received); } + + +/**************************************************************************** + do a directory listing, calling fn on each file found + this auto-switches between old and new style + ****************************************************************************/ +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state) +{ + if (cli->protocol <= PROTOCOL_LANMAN1) { + return cli_list_old(cli, Mask, attribute, fn, state); + } + return cli_list_new(cli, Mask, attribute, fn, state); +} diff --git a/source/libsmb/climessage.c b/source/libsmb/climessage.c index c15fdbce8c5..87f81754599 100644 --- a/source/libsmb/climessage.c +++ b/source/libsmb/climessage.c @@ -41,15 +41,13 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,username); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, username, -1, + STR_TERMINATE|STR_CONVERT); *p++ = 4; - pstrcpy(p,host); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, host, -1, + STR_TERMINATE|STR_CONVERT); - set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, p); cli_send_smb(cli); diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c index 085b1c35bb9..5050caf0732 100644 --- a/source/libsmb/clirap.c +++ b/source/libsmb/clirap.c @@ -27,18 +27,15 @@ /**************************************************************************** Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, char *data, uint32 data_count, uint32 max_data_count, char **rparam, uint32 *rparam_count, char **rdata, uint32 *rdata_count) { - if (pipe_name_len == 0) - pipe_name_len = strlen(pipe_name); - cli_send_trans(cli, SMBtrans, - pipe_name, pipe_name_len, + pipe_name, 0,0, /* fid, flags */ setup, setup_count, max_setup_count, params, param_count, max_param_count, @@ -59,8 +56,8 @@ BOOL cli_api(struct cli_state *cli, char **rdata, int *rdrcnt) { cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ - 0,0, /* fid, flags */ + PIPE_LANMAN, /* Name */ + 0,0, /* fid, flags */ NULL,0,0, /* Setup, length, max */ param, prcnt, mprcnt, /* Params, length, max */ data, drcnt, mdrcnt /* Data, length, max */ @@ -137,7 +134,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state) { char *rparam = NULL; char *rdata = NULL; @@ -182,9 +179,12 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co int type = SVAL(p,14); int comment_offset = IVAL(p,16) & 0xFFFF; char *cmnt = comment_offset?(rdata+comment_offset-converter):""; - dos_to_unix(sname,True); - dos_to_unix(cmnt,True); - fn(sname, type, cmnt); + pstring s1, s2; + + pstrcpy(s1, dos_to_unix(sname, False)); + pstrcpy(s2, dos_to_unix(cmnt, False)); + + fn(s1, type, s2, state); } } else { DEBUG(4,("NetShareEnum res=%d\n", res)); @@ -210,7 +210,8 @@ The callback function takes 3 arguments: the machine name, the server type and the comment. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)) + void (*fn)(const char *, uint32, const char *, void *), + void *state) { char *rparam = NULL; char *rdata = NULL; @@ -219,7 +220,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, pstring param; int uLevel = 1; int count = -1; - + /* send a SMBtrans command with api NetServerEnum */ p = param; SSVAL(p,0,0x68); /* api number */ @@ -228,17 +229,16 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = skip_string(p,1); pstrcpy(p,"B16BBDz"); - + p = skip_string(p,1); SSVAL(p,0,uLevel); SSVAL(p,2,CLI_BUFFER_SIZE); p += 4; SIVAL(p,0,stype); p += 4; - - pstrcpy(p, workgroup); - unix_to_dos(p, True); - p = skip_string(p,1); + + p += clistr_push(cli, p, workgroup, -1, + STR_TERMINATE | STR_CONVERT | STR_ASCII); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ @@ -259,13 +259,15 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, char *sname = p; int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; char *cmnt = comment_offset?(rdata+comment_offset):""; + pstring s1, s2; + if (comment_offset < 0 || comment_offset > rdrcnt) continue; stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - dos_to_unix(sname, True); - dos_to_unix(cmnt, True); - fn(sname, stype, cmnt); + pstrcpy(s1, dos_to_unix(sname, False)); + pstrcpy(s2, dos_to_unix(cmnt, False)); + fn(s1, stype, s2, state); } } } @@ -349,7 +351,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char data_len = 532; if (cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ + PIPE_LANMAN, /* name */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ @@ -391,17 +393,19 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, int count=8; BOOL ret; time_t (*date_fn)(void *); + char *p; - param_len = strlen(fname) + 7; + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_INFO_STANDARD); + p += 6; + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT); - memset(param, 0, param_len); - SSVAL(param, 0, SMB_INFO_STANDARD); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); + param_len = PTR_DIFF(p, param); do { ret = (cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ + NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ @@ -465,16 +469,18 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; + char *p; - param_len = strlen(fname) + 7; + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); + p += 6; + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT); - memset(param, 0, param_len); - SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); + param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ + NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ @@ -546,7 +552,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ + NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ @@ -592,3 +598,46 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return True; } +/**************************************************************************** +send a qfileinfo call +****************************************************************************/ +BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QFILEINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + /* if its a win95 server then fail this - win95 totally screws it + up */ + if (cli->win95) return False; + + param_len = 4; + + memset(param, 0, param_len); + SSVAL(param, 0, fnum); + SSVAL(param, 2, level); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + memcpy(outdata, rdata, data_len); + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c index 86a51da8352..458532cb2ed 100644 --- a/source/libsmb/clireadwrite.c +++ b/source/libsmb/clireadwrite.c @@ -26,7 +26,8 @@ /**************************************************************************** issue a single SMBread and don't wait for a reply ****************************************************************************/ -static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, + +static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { memset(cli->outbuf,'\0',smb_size); @@ -45,92 +46,88 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli); + return cli_send_smb(cli); } /**************************************************************************** - read from a file + Read size bytes at offset offset using SMBreadX. ****************************************************************************/ -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) + +ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { + uint32 ecode; + uint8 eclass; char *p; - int total = -1; - int issued=0; - int received=0; -/* - * There is a problem in this code when mpx is more than one. - * for some reason files can get corrupted when being read. - * Until we understand this fully I am serializing reads (one - * read/one reply) for now. JRA. - */ -#if 0 - int mpx = MAX(cli->max_mux-1, 1); -#else - int mpx = 1; -#endif - int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int mid; - int blocks = (size + (block-1)) / block; + int size2; + int readsize; + ssize_t total = 0; - if (size == 0) return 0; + if (size == 0) + return 0; - while (received < blocks) { - int size2; + /* + * Set readsize to the maximum size we can handle in one readX, + * rounded down to a multiple of 1024. + */ - while (issued - received < mpx && issued < blocks) { - int size1 = MIN(block, size-issued*block); - cli_issue_read(cli, fnum, offset+issued*block, size1, issued); - issued++; - } + readsize = (cli->max_xmit - (smb_size+32)) & ~1023; - if (!cli_receive_smb(cli)) { - return total; - } + while (total < size) { + readsize = MIN(readsize, size-total); - received++; - mid = SVAL(cli->inbuf, smb_mid) - cli->mid; - size2 = SVAL(cli->inbuf, smb_vwv5); + /* Issue a read and receive a reply */ - if (CVAL(cli->inbuf,smb_rcls) != 0) { - blocks = MIN(blocks, mid-1); - continue; - } + if (!cli_issue_read(cli, fnum, offset, readsize, 0)) + return -1; - if (size2 <= 0) { - blocks = MIN(blocks, mid-1); - /* this distinguishes EOF from an error */ - total = MAX(total, 0); - continue; - } + if (!cli_receive_smb(cli)) + return -1; + + /* + * Check for error. Because the client library doesn't support + * STATUS32, we need to check for and ignore the more data error + * for pipe support. + */ - if (size2 > block) { - DEBUG(0,("server returned more than we wanted!\n")); + if (cli_error(cli, &eclass, &ecode, NULL) && + (eclass != ERRDOS && ecode != ERRmoredata)) { return -1; } - if (mid >= issued) { - DEBUG(0,("invalid mid from server!\n")); + + size2 = SVAL(cli->inbuf, smb_vwv5); + + if (size2 > readsize) { + DEBUG(5,("server returned more than we wanted!\n")); + return -1; + } else if (size2 < 0) { + DEBUG(5,("read return < 0!\n")); return -1; } + + /* Copy data into buffer */ + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf + total, p, size2); - memcpy(buf+mid*block, p, size2); + total += size2; + offset += size2; - total = MAX(total, mid*block + size2); - } + /* + * If the server returned less than we asked for we're at EOF. + */ - while (received < issued) { - cli_receive_smb(cli); - received++; + if (size2 < readsize) + break; } - + return total; } - /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, + +static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, size_t size, int i) { char *p; @@ -138,7 +135,10 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,12,size,True); + if (size > 0xFFFF) + set_message(cli->outbuf,14,0,True); + else + set_message(cli->outbuf,12,0,True); CVAL(cli->outbuf,smb_com) = SMBwriteX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -152,17 +152,19 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_vwv7,mode); SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); + SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); memcpy(p, buf, size); + cli_setup_bcc(cli, p+size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); show_msg(cli->outbuf); - cli_send_smb(cli); + return cli_send_smb(cli); } /**************************************************************************** @@ -172,6 +174,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 0x0004 use raw named pipe protocol 0x0008 start of message mode named pipe protocol ****************************************************************************/ + ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, char *buf, off_t offset, size_t size) @@ -185,45 +188,39 @@ ssize_t cli_write(struct cli_state *cli, while (received < blocks) { - while ((issued - received < mpx) && (issued < blocks)) - { + while ((issued - received < mpx) && (issued < blocks)) { int bsent = issued * block; int size1 = MIN(block, size - bsent); - cli_issue_write(cli, fnum, offset + bsent, + if (!cli_issue_write(cli, fnum, offset + bsent, write_mode, buf + bsent, - size1, issued); + size1, issued)) + return -1; issued++; } if (!cli_receive_smb(cli)) - { return bwritten; - } received++; if (CVAL(cli->inbuf,smb_rcls) != 0) - { break; - } bwritten += SVAL(cli->inbuf, smb_vwv2); } while (received < issued && cli_receive_smb(cli)) - { received++; - } return bwritten; } - /**************************************************************************** write to a file using a SMBwrite and not bypassing 0 byte writes ****************************************************************************/ + ssize_t cli_smbwrite(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size1) { @@ -236,7 +233,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,5, 3 + size,True); + set_message(cli->outbuf,5, 0,True); CVAL(cli->outbuf,smb_com) = SMBwrite; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -249,20 +246,23 @@ ssize_t cli_smbwrite(struct cli_state *cli, p = smb_buf(cli->outbuf); *p++ = 1; - SSVAL(p, 0, size); - memcpy(p+2, buf, size); + SSVAL(p, 0, size); p += 2; + memcpy(p, buf, size); p += size; + + cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { + if (!cli_send_smb(cli)) + return -1; + + if (!cli_receive_smb(cli)) return -1; - } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (CVAL(cli->inbuf,smb_rcls) != 0) return -1; - } size = SVAL(cli->inbuf,smb_vwv0); - if (size == 0) break; + if (size == 0) + break; size1 -= size; total += size; @@ -270,4 +270,3 @@ ssize_t cli_smbwrite(struct cli_state *cli, return total; } - diff --git a/source/libsmb/clisecdesc.c b/source/libsmb/clisecdesc.c index 0b52d625131..69c7d5f73fd 100644 --- a/source/libsmb/clisecdesc.c +++ b/source/libsmb/clisecdesc.c @@ -28,12 +28,11 @@ /**************************************************************************** query the security descriptor for a open file ****************************************************************************/ -SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) +SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx) { char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx; prs_struct pd; SEC_DESC *psd = NULL; @@ -58,11 +57,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) goto cleanup; } - if ((mem_ctx = talloc_init()) == NULL) { - DEBUG(0,("talloc_init failed.\n")); - goto cleanup; - } - prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); prs_append_data(&pd, rdata, rdata_count); pd.data_offset = 0; @@ -74,7 +68,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) cleanup: - talloc_destroy(mem_ctx); safe_free(rparam); safe_free(rdata); @@ -82,9 +75,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) return psd; } - - - /**************************************************************************** set the security descriptor for a open file ****************************************************************************/ @@ -143,4 +133,3 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) prs_mem_free(&pd); return ret; } - diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c index 5cd6ae30ce0..d21d179126a 100644 --- a/source/libsmb/clitrans.c +++ b/source/libsmb/clitrans.c @@ -28,7 +28,7 @@ send a SMB trans or trans2 request ****************************************************************************/ BOOL cli_send_trans(struct cli_state *cli, int trans, - char *name, int pipe_name_len, + char *pipe_name, int fid, int flags, uint16 *setup, int lsetup, int msetup, char *param, int lparam, int mparam, @@ -39,6 +39,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, int tot_data=0,tot_param=0; char *outdata,*outparam; char *p; + int pipe_name_len=0; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); @@ -49,7 +50,11 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); - outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); + if (pipe_name) { + pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE); + } + + outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3); outdata = outparam+this_lparam; /* primary request */ @@ -68,9 +73,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, for (i=0;i<lsetup;i++) /* setup[] */ SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); - if (trans==SMBtrans) { - memcpy(p,name, pipe_name_len + 1); /* name[] */ - } else { + if (trans != SMBtrans) { *p++ = 0; /* put in a null smb_name */ *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ } @@ -78,8 +81,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outparam,param,this_lparam); if (this_ldata) /* data[] */ memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); @@ -119,8 +121,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outparam,param+tot_param,this_lparam); if (this_ldata) /* data[] */ memcpy(outdata,data+tot_data,this_ldata); - set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); @@ -288,8 +289,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, if (this_ldata) /* data[] */ memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,19+lsetup, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); @@ -328,8 +328,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, memcpy(outparam,param+tot_param,this_lparam); if (this_ldata) /* data[] */ memcpy(outdata,data+tot_data,this_ldata); - set_message(cli->outbuf,18, - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c index 816804753e7..465198dfad4 100644 --- a/source/libsmb/namequery.c +++ b/source/libsmb/namequery.c @@ -190,6 +190,96 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name) return True; } +/**************************************************************************** + Do a NetBIOS name registation to try to claim a name ... +***************************************************************************/ +BOOL name_register(int fd, const char *name, int name_type, + struct in_addr name_ip, int opcode, + BOOL bcast, + struct in_addr to_ip, int *count) +{ + int retries = 3; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + struct in_addr register_ip; + + DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip))); + + register_ip.s_addr = name_ip.s_addr; /* Fix this ... */ + + bzero((char *)&p, sizeof(p)); + + *count = 0; + + nmb->header.name_trn_id = generate_trn_id(); + nmb->header.opcode = opcode; + nmb->header.response = False; + nmb->header.nm_flags.bcast = False; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = True; /* ? */ + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = True; + + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 1; + + make_nmb_name(&nmb->question.question_name, name, name_type); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + /* Now, create the additional stuff for a registration request */ + + if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) { + + DEBUG(0, ("name_register: malloc fail for additional record.\n")); + return False; + + } + + bzero((char *)nmb->additional, sizeof(struct res_rec)); + + nmb->additional->rr_name = nmb->question.question_name; + nmb->additional->rr_type = RR_TYPE_NB; + nmb->additional->rr_class = RR_CLASS_IN; + + /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */ + if (nmb->header.nm_flags.bcast) + nmb->additional->ttl = PERMANENT_TTL; + else + nmb->additional->ttl = lp_max_ttl(); + + nmb->additional->rdlength = 6; + + nmb->additional->rdata[0] = NB_MFLAG & 0xFF; + + /* Set the address for the name we are registering. */ + putip(&nmb->additional->rdata[2], ®ister_ip); + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return False; + + retries--; + + if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { + debug_nmb_packet(p2); + free(p2); /* No memory leaks ... */ + } + + return True; +} /**************************************************************************** Do a netbios name query to find someones IP. @@ -456,6 +546,65 @@ void endlmhosts(FILE *fp) fclose(fp); } +BOOL name_register_wins(const char *name, int name_type) +{ + int sock, i, return_count; + int num_interfaces = iface_count(); + struct in_addr sendto_ip; + + /* + * Do a broadcast register ... + */ + + if (!lp_wins_server()) + return False; + + DEBUG(4, ("name_register_wins:Registering my name %s on %s\n", name, lp_wins_server())); + + sock = open_socket_in(SOCK_DGRAM, 0, 3, + interpret_addr("0.0.0.0"), True); + + if (sock == -1) return False; + + set_socket_options(sock, "SO_BROADCAST"); + + sendto_ip.s_addr = inet_addr(lp_wins_server()); + + if (num_interfaces > 1) { + + for (i = 0; i < num_interfaces; i++) { + + if (!name_register(sock, name, name_type, *iface_n_ip(i), + NMB_NAME_MULTIHOMED_REG_OPCODE, + True, sendto_ip, &return_count)) { + + close(sock); + return False; + + } + + } + + } + else { + + if (!name_register(sock, name, name_type, *iface_n_ip(0), + NMB_NAME_REG_OPCODE, + True, sendto_ip, &return_count)) { + + close(sock); + return False; + + } + + } + + close(sock); + + return True; + +} + /******************************************************** Resolve via "bcast" method. *********************************************************/ @@ -623,7 +772,7 @@ static BOOL resolve_hosts(const char *name, DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name)); - if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { struct in_addr return_ip; putip((char *)&return_ip,(char *)hp->h_addr); *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); diff --git a/source/libsmb/pwd_cache.c b/source/libsmb/pwd_cache.c index 26b1d192f09..420b49ed2e7 100644 --- a/source/libsmb/pwd_cache.c +++ b/source/libsmb/pwd_cache.c @@ -103,11 +103,21 @@ void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) user_pass = (char*)getpass(passwd_report); + /* + * Do not assume that an empty string is a NULL password. + * If you do this will break the session key generation for + * and account with an emtpy password. If you wish to use + * a NULL password, use the -N option to smbclient and rpcclient + * --jerry + */ +#if 0 if (user_pass == NULL || user_pass[0] == 0) { pwd_set_nullpwd(pwd); } else if (do_encrypt) +#endif + if (do_encrypt) { pwd_make_lm_nt_16(pwd, user_pass); } diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c index d0e1c6e85fb..7e8a9a5b89e 100644 --- a/source/libsmb/smbdes.c +++ b/source/libsmb/smbdes.c @@ -381,7 +381,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) s_box[ind] = s_box[j]; s_box[j] = tc; } - for( ind = 0; ind < (val ? 516 : 16); ind++) + for( ind = 0; ind < val; ind++) { unsigned char tc; unsigned char t; diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index caf92567879..7efb2bb9b31 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -223,7 +223,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ DEBUG(100,("make_oem_passwd_hash\n")); dump_data(100, data, 516); #endif - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); return True; } diff --git a/source/libsmb/unexpected.c b/source/libsmb/unexpected.c index 6c5dd611a9c..4aa566de5b2 100644 --- a/source/libsmb/unexpected.c +++ b/source/libsmb/unexpected.c @@ -49,7 +49,7 @@ void unexpected_packet(struct packet_struct *p) int len=0; if (!tdbd) { - tdbd = tdb_open(lock_path("unexpected.tdb"), 1, + tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644); if (!tdbd) { @@ -151,7 +151,7 @@ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, { TDB_CONTEXT *tdb2; - tdb2 = tdb_open(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0); + tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0); if (!tdb2) return NULL; matched_packet = NULL; diff --git a/source/locking/brlock.c b/source/locking/brlock.c index 175ab5c9b0a..7f3ec6757e3 100644 --- a/source/locking/brlock.c +++ b/source/locking/brlock.c @@ -113,12 +113,16 @@ static BOOL brl_conflict(struct lock_struct *lck1, /**************************************************************************** -delete a record if it is for a dead process + Delete a record if it is for a dead process, if check_self is true, then + delete any records belonging to this pid also (there shouldn't be any). ****************************************************************************/ + static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct lock_struct *locks; int count, i; + BOOL check_self = *(BOOL *)state; + pid_t mypid = sys_getpid(); tdb_chainlock(tdb, kbuf); @@ -128,7 +132,20 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat for (i=0; i<count; i++) { struct lock_struct *lock = &locks[i]; - if (process_exists(lock->context.pid)) continue; + /* If check_self is true we want to remove our own records. */ + if (check_self && (mypid == lock->context.pid)) { + + DEBUG(0,("brlock : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", + (unsigned int)lock->context.pid )); + + } else if (process_exists(lock->context.pid)) { + + DEBUG(10,("brlock : delete_fn. pid %u exists.\n", (unsigned int)lock->context.pid )); + continue; + } + + DEBUG(10,("brlock : delete_fn. Deleting record for process %u\n", + (unsigned int)lock->context.pid )); if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], @@ -152,10 +169,14 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat /**************************************************************************** Open up the brlock.tdb database. ****************************************************************************/ + void brl_init(int read_only) { - if (tdb) return; - tdb = tdb_open(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, + BOOL check_self = False; + + if (tdb) + return; + tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); @@ -163,11 +184,27 @@ void brl_init(int read_only) } /* delete any dead locks */ - if (!read_only) { - tdb_traverse(tdb, delete_fn, NULL); - } + if (!read_only) + tdb_traverse(tdb, delete_fn, &check_self); } +/**************************************************************************** + Close down the brlock.tdb database. +****************************************************************************/ + +void brl_shutdown(int read_only) +{ + BOOL check_self = True; + + if (!tdb) + return; + + /* delete any dead locks */ + if (!read_only) + tdb_traverse(tdb, delete_fn, &check_self); + + tdb_close(tdb); +} /**************************************************************************** Lock a range of bytes. @@ -304,13 +341,33 @@ smbpid = %u, pid = %u, tid = %u\n", } /**************************************************************************** + Check to see if this lock conflicts, but ignore our own locks on the + same fnum only. +****************************************************************************/ + +static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) +{ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) + return False; + + if (brl_same_context(&lck1->context, &lck2->context) && + lck1->fnum == lck2->fnum) + return False; + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) return False; + + return True; +} + +/**************************************************************************** Test if we could add a lock if we wanted to. ****************************************************************************/ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum brl_type lock_type) + enum brl_type lock_type, int check_self) { TDB_DATA kbuf, dbuf; int count, i; @@ -336,8 +393,15 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); for (i=0; i<count; i++) { - if (brl_conflict(&locks[i], &lock)) { - goto fail; + if (check_self) { + if (brl_conflict(&locks[i], &lock)) + goto fail; + } else { + /* + * Our own locks don't conflict. + */ + if (brl_conflict_other(&locks[i], &lock)) + goto fail; } } } diff --git a/source/locking/locking.c b/source/locking/locking.c index 5824287e913..067b1dc0ddf 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -37,7 +37,7 @@ #include "includes.h" extern int DEBUGLEVEL; -int global_smbpid; +uint16 global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; @@ -53,11 +53,14 @@ static const char *lock_type_name(enum brl_type lock_type) /**************************************************************************** Utility function called to see if a file region is locked. + If check_self is True, then checks on our own fd with the same locking context + are still made. If check_self is False, then checks are not made on our own fd + with the same locking context are not made. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_BIG_UINT count,SMB_BIG_UINT offset, - enum brl_type lock_type) + enum brl_type lock_type, BOOL check_self) { int snum = SNUM(conn); BOOL ret; @@ -70,16 +73,25 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, sys_getpid(), conn->cnum, - offset, count, lock_type); + offset, count, lock_type, check_self); + + DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", + (double)offset, (double)count, ret ? "locked" : "unlocked", + fsp->fsp_name )); /* * There is no lock held by an SMB daemon, check to * see if there is a POSIX lock from a UNIX or NFS process. */ - if(!ret && lp_posix_locking(snum)) + if(!ret && lp_posix_locking(snum)) { ret = is_posix_locked(fsp, offset, count, lock_type); + DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n", + (double)offset, (double)count, ret ? "locked" : "unlocked", + fsp->fsp_name )); + } + return ret; } @@ -87,7 +99,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(files_struct *fsp,connection_struct *conn, +BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, int *eclass,uint32 *ecode) { @@ -107,7 +119,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, + lock_pid, sys_getpid(), conn->cnum, offset, count, lock_type); @@ -127,7 +139,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, + lock_pid, sys_getpid(), conn->cnum, offset, count); } } @@ -145,7 +157,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, Utility function called by unlocking requests. ****************************************************************************/ -BOOL do_unlock(files_struct *fsp,connection_struct *conn, +BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset, int *eclass,uint32 *ecode) { @@ -156,7 +168,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { *eclass = ERRDOS; - *ecode = ERRlock; + *ecode = ERRbadfid; return False; } @@ -170,12 +182,12 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, */ ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, offset, count); + lock_pid, sys_getpid(), conn->cnum, offset, count); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); *eclass = ERRDOS; - *ecode = ERRlock; + *ecode = ERRnotlocked; return False; } @@ -215,15 +227,74 @@ void locking_close_file(files_struct *fsp) } /**************************************************************************** + Delete a record if it is for a dead process, if check_self is true, then + delete any records belonging to this pid also (there shouldn't be any). + This function is only called on locking startup and shutdown. +****************************************************************************/ + +static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +{ + struct locking_data *data; + share_mode_entry *shares; + int i, del_count=0; + pid_t mypid = sys_getpid(); + BOOL check_self = *(BOOL *)state; + + tdb_chainlock(tdb, kbuf); + + data = (struct locking_data *)dbuf.dptr; + shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + + for (i=0;i<data->num_share_mode_entries;) { + + if (check_self && (shares[i].pid == mypid)) { + DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", + (unsigned int)shares[i].pid )); + } else if (!process_exists(shares[i].pid)) { + DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Entry for pid %u and it no longer exists !\n", + (unsigned int)shares[i].pid )); + } else { + /* Process exists, leave this record alone. */ + i++; + continue; + } + + data->num_share_mode_entries--; + memmove(&shares[i], &shares[i+1], + dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); + del_count++; + + } + + /* the record has shrunk a bit */ + dbuf.dsize -= del_count * sizeof(*shares); + + /* store it back in the database */ + if (data->num_share_mode_entries == 0) + tdb_delete(ttdb, kbuf); + else + tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE); + + tdb_chainunlock(tdb, kbuf); + return 0; +} + +/**************************************************************************** Initialise the locking functions. ****************************************************************************/ + +static int open_read_only; + BOOL locking_init(int read_only) { + BOOL check_self = False; + brl_init(read_only); - if (tdb) return True; + if (tdb) + return True; - tdb = tdb_open(lock_path("locking.tdb"), + tdb = tdb_open_log(lock_path("locking.tdb"), 0, TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); @@ -236,15 +307,35 @@ BOOL locking_init(int read_only) if (!posix_locking_init(read_only)) return False; + /* delete any dead locks */ + if (!read_only) + tdb_traverse(tdb, delete_fn, &check_self); + + open_read_only = read_only; + return True; } /******************************************************************* Deinitialize the share_mode management. ******************************************************************/ + BOOL locking_end(void) { - if (tdb && tdb_close(tdb) != 0) return False; + BOOL check_self = True; + + brl_shutdown(open_read_only); + if (tdb) { + + /* delete any dead locks */ + + if (!open_read_only) + tdb_traverse(tdb, delete_fn, &check_self); + + if (tdb_close(tdb) != 0) + return False; + } + return True; } diff --git a/source/locking/posix.c b/source/locking/posix.c index 75fc6272b5a..2a8a7aacd73 100644 --- a/source/locking/posix.c +++ b/source/locking/posix.c @@ -25,7 +25,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern int global_smbpid; /* * The POSIX locking database handle. @@ -1350,14 +1349,14 @@ BOOL posix_locking_init(int read_only) return True; if (!posix_lock_tdb) - posix_lock_tdb = tdb_open(NULL, 0, TDB_INTERNAL, + posix_lock_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!posix_lock_tdb) { DEBUG(0,("Failed to open POSIX byte range locking database.\n")); return False; } if (!posix_pending_close_tdb) - posix_pending_close_tdb = tdb_open(NULL, 0, TDB_INTERNAL, + posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!posix_pending_close_tdb) { DEBUG(0,("Failed to open POSIX pending close database.\n")); diff --git a/source/msdfs/msdfs.c b/source/msdfs/msdfs.c index b93590fcd24..b2530a3d7f2 100644 --- a/source/msdfs/msdfs.c +++ b/source/msdfs/msdfs.c @@ -30,285 +30,298 @@ extern uint32 global_client_caps; /********************************************************************** Create a tcon relative path from a dfs_path structure **********************************************************************/ + static void create_nondfs_path(char* pathname, struct dfs_path* pdp) { - pstrcpy(pathname,pdp->volumename); - pstrcat(pathname,"\\"); - pstrcat(pathname,pdp->restofthepath); + pstrcpy(pathname,pdp->volumename); + pstrcat(pathname,"\\"); + pstrcat(pathname,pdp->restofthepath); } /********************************************************************** Parse the pathname of the form \hostname\service\volume\restofthepath into the dfs_path structure **********************************************************************/ + static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) { - pstring pathname_local; - char* p,*temp; - - pstrcpy(pathname_local,pathname); - p = temp = pathname_local; - - ZERO_STRUCTP(pdp); - - trim_string(temp,"\\","\\"); - DEBUG(10,("temp in parse_dfs_path: .%s. after trimming \\'s\n",temp)); - - /* now tokenize */ - /* parse out hostname */ - p = strchr(temp,'\\'); - if(p == NULL) - return False; - *p = '\0'; - pstrcpy(pdp->hostname,temp); - DEBUG(10,("hostname: %s\n",pdp->hostname)); - - /* parse out servicename */ - temp = p+1; - p = strchr(temp,'\\'); - if(p == NULL) - { - pstrcpy(pdp->servicename,temp); - return True; - } - *p = '\0'; - pstrcpy(pdp->servicename,temp); - DEBUG(10,("servicename: %s\n",pdp->servicename)); - - /* parse out volumename */ - temp = p+1; - p = strchr(temp,'\\'); - if(p == NULL) - { - pstrcpy(pdp->volumename,temp); - return True; - } - *p = '\0'; - pstrcpy(pdp->volumename,temp); - DEBUG(10,("volumename: %s\n",pdp->volumename)); - - /* remaining path .. */ - pstrcpy(pdp->restofthepath,p+1); - DEBUG(10,("rest of the path: %s\n",pdp->restofthepath)); - return True; + pstring pathname_local; + char* p,*temp; + + pstrcpy(pathname_local,pathname); + p = temp = pathname_local; + + ZERO_STRUCTP(pdp); + + trim_string(temp,"\\","\\"); + DEBUG(10,("temp in parse_dfs_path: .%s. after trimming \\'s\n",temp)); + + /* now tokenize */ + /* parse out hostname */ + p = strchr(temp,'\\'); + if(p == NULL) + return False; + *p = '\0'; + pstrcpy(pdp->hostname,temp); + DEBUG(10,("hostname: %s\n",pdp->hostname)); + + /* parse out servicename */ + temp = p+1; + p = strchr(temp,'\\'); + if(p == NULL) { + pstrcpy(pdp->servicename,temp); + return True; + } + *p = '\0'; + pstrcpy(pdp->servicename,temp); + DEBUG(10,("servicename: %s\n",pdp->servicename)); + + /* parse out volumename */ + temp = p+1; + p = strchr(temp,'\\'); + if(p == NULL) { + pstrcpy(pdp->volumename,temp); + return True; + } + *p = '\0'; + pstrcpy(pdp->volumename,temp); + DEBUG(10,("volumename: %s\n",pdp->volumename)); + + /* remaining path .. */ + pstrcpy(pdp->restofthepath,p+1); + DEBUG(10,("rest of the path: %s\n",pdp->restofthepath)); + return True; +} + +/******************************************************** + Fake up a connection struct for the VFS layer. +*********************************************************/ + +static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) +{ + ZERO_STRUCTP(conn); + conn->service = snum; + conn->connectpath = path; + + if (!vfs_init(conn)) { + DEBUG(0,("create_conn_struct: vfs init failed.\n")); + return False; + } + return True; } /********************************************************************** Forms a valid Unix pathname from the junction **********************************************************************/ -static BOOL form_path_from_junction(struct junction_map* jn, char* path, - int max_pathlen) + +static BOOL form_path_from_junction(struct junction_map* jn, char* path, int max_pathlen, + connection_struct *conn) { - int snum; + int snum; - if(!path || !jn) - return False; + if(!path || !jn) + return False; - snum = lp_servicenumber(jn->service_name); - if(snum < 0) - return False; + snum = lp_servicenumber(jn->service_name); + if(snum < 0) + return False; - safe_strcpy(path, lp_pathname(snum), max_pathlen-1); - safe_strcat(path, "/", max_pathlen-1); - strlower(jn->volume_name); - safe_strcat(path, jn->volume_name, max_pathlen-1); - return True; + safe_strcpy(path, lp_pathname(snum), max_pathlen-1); + safe_strcat(path, "/", max_pathlen-1); + strlower(jn->volume_name); + safe_strcat(path, jn->volume_name, max_pathlen-1); + + if (!create_conn_struct(conn, snum, path)) + return False; + + return True; } /********************************************************************** Creates a junction structure from the Dfs pathname **********************************************************************/ + BOOL create_junction(char* pathname, struct junction_map* jn) { - struct dfs_path dp; + struct dfs_path dp; - parse_dfs_path(pathname,&dp); - - /* check if path is dfs : check hostname is the first token */ - if(global_myname && (strcasecmp(global_myname,dp.hostname)!=0)) - { - DEBUG(4,("create_junction: Invalid hostname %s in dfs path %s\n", - dp.hostname, pathname)); - return False; - } - - /* Check for a non-DFS share */ - if(!lp_msdfs_root(lp_servicenumber(dp.servicename))) - { - DEBUG(4,("create_junction: %s is not an msdfs root.\n", - dp.servicename)); - return False; - } + parse_dfs_path(pathname,&dp); + + /* check if path is dfs : check hostname is the first token */ + if(global_myname && (strcasecmp(global_myname,dp.hostname)!=0)) { + DEBUG(4,("create_junction: Invalid hostname %s in dfs path %s\n", dp.hostname, pathname)); + return False; + } - pstrcpy(jn->service_name,dp.servicename); - pstrcpy(jn->volume_name,dp.volumename); - return True; + /* Check for a non-DFS share */ + if(!lp_msdfs_root(lp_servicenumber(dp.servicename))) { + DEBUG(4,("create_junction: %s is not an msdfs root.\n", dp.servicename)); + return False; + } + + pstrcpy(jn->service_name,dp.servicename); + pstrcpy(jn->volume_name,dp.volumename); + return True; } /********************************************************************** Parse the contents of a symlink to verify if it is an msdfs referral A valid referral is of the form: msdfs:server1\share1,server2\share2 **********************************************************************/ + static BOOL parse_symlink(char* buf,struct referral** preflist, int* refcount) { - pstring temp; - char* prot; - char* alt_path[MAX_REFERRAL_COUNT]; - int count=0, i; - struct referral* reflist; + pstring temp; + char* prot; + char* alt_path[MAX_REFERRAL_COUNT]; + int count=0, i; + struct referral* reflist; - pstrcpy(temp,buf); + pstrcpy(temp,buf); - prot = strtok(temp,":"); - - if(!strequal(prot, "msdfs")) - return False; - - /* It's an msdfs referral */ - if(!preflist) - return True; - - /* parse out the alternate paths */ - while(((alt_path[count] = strtok(NULL,",")) != NULL) - && count<MAX_REFERRAL_COUNT) - count++; - - DEBUG(10,("parse_symlink: count=%d\n", count)); - reflist = *preflist = (struct referral*) malloc(count * - sizeof(struct referral)); - if(reflist == NULL) - { - DEBUG(0,("parse_symlink: Malloc failed!\n")); - return False; - } + prot = strtok(temp,":"); + + if(!strequal(prot, "msdfs")) + return False; + + /* It's an msdfs referral */ + if(!preflist) + return True; + + /* parse out the alternate paths */ + while(((alt_path[count] = strtok(NULL,",")) != NULL) && count<MAX_REFERRAL_COUNT) + count++; + + DEBUG(10,("parse_symlink: count=%d\n", count)); + + reflist = *preflist = (struct referral*) malloc(count * sizeof(struct referral)); + if(reflist == NULL) { + DEBUG(0,("parse_symlink: Malloc failed!\n")); + return False; + } - for(i=0;i<count;i++) - { - /* replace / in the alternate path by a \ */ - char* p = strchr(alt_path[i],'/'); - if(p) *p = '\\'; - - pstrcpy(reflist[i].alternate_path, "\\"); - pstrcat(reflist[i].alternate_path, alt_path[i]); - reflist[i].proximity = 0; - reflist[i].ttl = REFERRAL_TTL; - DEBUG(10, ("parse_symlink: Created alt path: %s\n", - reflist[i].alternate_path)); - } - - if(refcount) - *refcount = count; - - return True; + for(i=0;i<count;i++) { + /* replace / in the alternate path by a \ */ + char* p = strchr(alt_path[i],'/'); + if(p) + *p = '\\'; + + pstrcpy(reflist[i].alternate_path, "\\"); + pstrcat(reflist[i].alternate_path, alt_path[i]); + reflist[i].proximity = 0; + reflist[i].ttl = REFERRAL_TTL; + DEBUG(10, ("parse_symlink: Created alt path: %s\n", reflist[i].alternate_path)); + } + + if(refcount) + *refcount = count; + + return True; } /********************************************************************** Returns true if the unix path is a valid msdfs symlink **********************************************************************/ + BOOL is_msdfs_link(connection_struct* conn, char* path) { - SMB_STRUCT_STAT st; - pstring referral; - int referral_len = 0; + SMB_STRUCT_STAT st; + pstring referral; + int referral_len = 0; - if(!path || !conn) - return False; + if(!path || !conn) + return False; - strlower(path); + strlower(path); - if(conn->vfs_ops.lstat(conn,dos_to_unix(path,False),&st) != 0) - { - DEBUG(5,("is_msdfs_link: %s does not exist.\n",path)); - return False; - } + if(conn->vfs_ops.lstat(conn,dos_to_unix(path,False),&st) != 0) { + DEBUG(5,("is_msdfs_link: %s does not exist.\n",path)); + return False; + } - if(S_ISLNK(st.st_mode)) - { - /* open the link and read it */ - referral_len = readlink(path, referral, sizeof(pstring)); - if(referral_len == -1) - DEBUG(0,("is_msdfs_link: Error reading msdfs link %s: %s\n", - path, strerror(errno))); - - referral[referral_len] = '\0'; - DEBUG(5,("is_msdfs_link: %s -> %s\n",path,referral)); - if(parse_symlink(referral, NULL, NULL)) - return True; - } - return False; + if(S_ISLNK(st.st_mode)) { + /* open the link and read it */ + referral_len = conn->vfs_ops.readlink(conn, path, referral, sizeof(pstring)); + if(referral_len == -1) + DEBUG(0,("is_msdfs_link: Error reading msdfs link %s: %s\n", path, strerror(errno))); + + referral[referral_len] = '\0'; + DEBUG(5,("is_msdfs_link: %s -> %s\n",path,referral)); + if(parse_symlink(referral, NULL, NULL)) + return True; + } + return False; } /********************************************************************** Fills in the junction_map struct with the referrals from the symbolic link **********************************************************************/ + BOOL get_referred_path(struct junction_map* junction) { - fstring path; - pstring buf; - SMB_STRUCT_STAT st; - - if(!form_path_from_junction(junction, path, sizeof(path))) - return False; + pstring path; + pstring buf; + SMB_STRUCT_STAT st; + connection_struct conns; + connection_struct *conn = &conns; + + if(!form_path_from_junction(junction, path, sizeof(path), conn)) + return False; - DEBUG(5,("get_referred_path: lstat target: %s\n", path)); + DEBUG(5,("get_referred_path: lstat target: %s\n", path)); - if(lstat(dos_to_unix(path, False),&st) != 0) - { - DEBUG(5,("get_referred_path: %s does not exist.\n",path)); - return False; - } + if(conn->vfs_ops.lstat(conn,dos_to_unix(path, False),&st) != 0) { + DEBUG(5,("get_referred_path: %s does not exist.\n",path)); + return False; + } - if(S_ISLNK(st.st_mode)) - { - /* open the link and read it to get the dfs referral */ - int linkcnt = 0; - linkcnt = readlink(path, buf, sizeof(buf)); - buf[linkcnt] = '\0'; - DEBUG(5,("get_referred_path: Referral: %s\n",buf)); - if(parse_symlink(buf, &junction->referral_list, - &junction->referral_count)) - return True; - } - return False; + if(S_ISLNK(st.st_mode)) { + /* open the link and read it to get the dfs referral */ + int linkcnt = 0; + linkcnt = conn->vfs_ops.readlink(conn, path, buf, sizeof(buf)); + buf[linkcnt] = '\0'; + DEBUG(5,("get_referred_path: Referral: %s\n",buf)); + if(parse_symlink(buf, &junction->referral_list, &junction->referral_count)) + return True; + } + return False; } /************************************************************** Decides if given pathname is Dfs and if it should be redirected Converts pathname to non-dfs format if Dfs redirection not required **************************************************************/ + BOOL dfs_redirect(char* pathname, connection_struct* conn) { - struct dfs_path dp; - pstring temp; - fstring path; - - pstrcpy(temp,pathname); - - if(!lp_msdfs_root(SNUM(conn)) ) - return False; - - parse_dfs_path(pathname,&dp); - - if(global_myname && (strcasecmp(global_myname,dp.hostname)!=0)) - return False; - - /* check if need to redirect */ - fstrcpy(path, conn->connectpath); - fstrcat(path, "/"); - fstrcat(path, dp.volumename); - if(is_msdfs_link(conn, path)) - { - DEBUG(4,("dfs_redirect: Redirecting %s\n",temp)); - return True; - } - else - { - create_nondfs_path(pathname,&dp); - DEBUG(4,("dfs_redirect: Not redirecting %s. Converted to non-dfs pathname \'%s\'\n", - temp,pathname)); - return False; - } + struct dfs_path dp; + pstring temp; + fstring path; + + pstrcpy(temp,pathname); + + if(!lp_msdfs_root(SNUM(conn)) ) + return False; + + parse_dfs_path(pathname,&dp); + + if(global_myname && (strcasecmp(global_myname,dp.hostname)!=0)) + return False; + + /* check if need to redirect */ + fstrcpy(path, conn->connectpath); + fstrcat(path, "/"); + fstrcat(path, dp.volumename); + if(is_msdfs_link(conn, path)) { + DEBUG(4,("dfs_redirect: Redirecting %s\n",temp)); + return True; + } else { + create_nondfs_path(pathname,&dp); + DEBUG(4,("dfs_redirect: Not redirecting %s. Converted to non-dfs pathname \'%s\'\n", + temp,pathname)); + return False; + } } /* @@ -316,450 +329,434 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn) If the findfirst is for the dfs junction, then no redirection, if it is for the underlying directory contents, redirect. */ + BOOL dfs_findfirst_redirect(char* pathname, connection_struct* conn) { - struct dfs_path dp; + struct dfs_path dp; - pstring temp; - - pstrcpy(temp,pathname); - - /* Is the path Dfs-redirectable? */ - if(!dfs_redirect(temp,conn)) - { - pstrcpy(pathname,temp); - return False; - } - - parse_dfs_path(pathname,&dp); - DEBUG(8,("dfs_findfirst_redirect: path %s is in Dfs. dp.restofthepath=.%s.\n",pathname,dp.restofthepath)); - if(*(dp.restofthepath)) - return True; - else - { - create_nondfs_path(pathname,&dp); - return False; - } + pstring temp; + + pstrcpy(temp,pathname); + + /* Is the path Dfs-redirectable? */ + if(!dfs_redirect(temp,conn)) { + pstrcpy(pathname,temp); + return False; + } + + parse_dfs_path(pathname,&dp); + DEBUG(8,("dfs_findfirst_redirect: path %s is in Dfs. dp.restofthepath=.%s.\n", + pathname,dp.restofthepath)); + if(!(*(dp.restofthepath))) { + create_nondfs_path(pathname,&dp); + return False; + } + + return True; } static int setup_ver2_dfs_referral(char* pathname, char** ppdata, struct junction_map* junction, BOOL self_referral) { - char* pdata = *ppdata; - - unsigned char uni_requestedpath[1024]; - int uni_reqpathoffset1,uni_reqpathoffset2; - int uni_curroffset; - int requestedpathlen=0; - int offset; - int reply_size = 0; - int i=0; - - DEBUG(10,("setting up version2 referral\nRequested path:\n")); - - requestedpathlen = (dos_struni2(uni_requestedpath,pathname,512)+1)*2; - - dump_data(10,uni_requestedpath,requestedpathlen); - - DEBUG(10,("ref count = %u\n",junction->referral_count)); - - uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + - VERSION2_REFERRAL_SIZE * junction->referral_count; - - uni_reqpathoffset2 = uni_reqpathoffset1 + requestedpathlen; - - uni_curroffset = uni_reqpathoffset2 + requestedpathlen; - - reply_size = REFERRAL_HEADER_SIZE + VERSION2_REFERRAL_SIZE*junction->referral_count + - 2 * requestedpathlen; - DEBUG(10,("reply_size: %u\n",reply_size)); - - /* add up the unicode lengths of all the referral paths */ - for(i=0;i<junction->referral_count;i++) - { - DEBUG(10,("referral %u : %s\n",i,junction->referral_list[i].alternate_path)); - reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2; - } - - DEBUG(10,("reply_size = %u\n",reply_size)); - /* add the unexplained 0x16 bytes */ - reply_size += 0x16; - - pdata = *ppdata = Realloc(pdata,reply_size); - if(pdata == NULL) - { - DEBUG(0,("malloc failed for Realloc!\n")); - return -1; - } - - /* copy in the dfs requested paths.. required for offset calculations */ - memcpy(pdata+uni_reqpathoffset1,uni_requestedpath,requestedpathlen); - memcpy(pdata+uni_reqpathoffset2,uni_requestedpath,requestedpathlen); - - - /* create the header */ - SSVAL(pdata,0,requestedpathlen-2); /* path consumed */ - SSVAL(pdata,2,junction->referral_count); /* number of referral in this pkt */ - if(self_referral) - SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER); - else - SIVAL(pdata,4,DFSREF_STORAGE_SERVER); - - offset = 8; - /* add the referral elements */ - for(i=0;i<junction->referral_count;i++) - { - struct referral* ref = &(junction->referral_list[i]); - int unilen; - - SSVAL(pdata,offset,2); /* version 2 */ - SSVAL(pdata,offset+2,VERSION2_REFERRAL_SIZE); - if(self_referral) - SSVAL(pdata,offset+4,1); - else - SSVAL(pdata,offset+4,0); - SSVAL(pdata,offset+6,0); /* ref_flags :use path_consumed bytes? */ - SIVAL(pdata,offset+8,ref->proximity); - SIVAL(pdata,offset+12,ref->ttl); - - SSVAL(pdata,offset+16,uni_reqpathoffset1-offset); - SSVAL(pdata,offset+18,uni_reqpathoffset2-offset); - /* copy referred path into current offset */ - unilen = (dos_struni2(pdata+uni_curroffset,ref->alternate_path,512) - +1)*2; - SSVAL(pdata,offset+20,uni_curroffset-offset); - - uni_curroffset += unilen; - offset += VERSION2_REFERRAL_SIZE; - } - /* add in the unexplained 22 (0x16) bytes at the end */ - memset(pdata+uni_curroffset,'\0',0x16); - free(junction->referral_list); - return reply_size; + char* pdata = *ppdata; + + unsigned char uni_requestedpath[1024]; + int uni_reqpathoffset1,uni_reqpathoffset2; + int uni_curroffset; + int requestedpathlen=0; + int offset; + int reply_size = 0; + int i=0; + + DEBUG(10,("setting up version2 referral\nRequested path:\n")); + + requestedpathlen = (dos_struni2(uni_requestedpath,pathname,512)+1)*2; + + dump_data(10,uni_requestedpath,requestedpathlen); + + DEBUG(10,("ref count = %u\n",junction->referral_count)); + + uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + + VERSION2_REFERRAL_SIZE * junction->referral_count; + + uni_reqpathoffset2 = uni_reqpathoffset1 + requestedpathlen; + + uni_curroffset = uni_reqpathoffset2 + requestedpathlen; + + reply_size = REFERRAL_HEADER_SIZE + VERSION2_REFERRAL_SIZE*junction->referral_count + + 2 * requestedpathlen; + DEBUG(10,("reply_size: %u\n",reply_size)); + + /* add up the unicode lengths of all the referral paths */ + for(i=0;i<junction->referral_count;i++) { + DEBUG(10,("referral %u : %s\n",i,junction->referral_list[i].alternate_path)); + reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2; + } + + DEBUG(10,("reply_size = %u\n",reply_size)); + /* add the unexplained 0x16 bytes */ + reply_size += 0x16; + + pdata = *ppdata = Realloc(pdata,reply_size); + if(pdata == NULL) { + DEBUG(0,("malloc failed for Realloc!\n")); + return -1; + } + + /* copy in the dfs requested paths.. required for offset calculations */ + memcpy(pdata+uni_reqpathoffset1,uni_requestedpath,requestedpathlen); + memcpy(pdata+uni_reqpathoffset2,uni_requestedpath,requestedpathlen); + + /* create the header */ + SSVAL(pdata,0,requestedpathlen-2); /* path consumed */ + SSVAL(pdata,2,junction->referral_count); /* number of referral in this pkt */ + if(self_referral) + SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER); + else + SIVAL(pdata,4,DFSREF_STORAGE_SERVER); + + offset = 8; + /* add the referral elements */ + for(i=0;i<junction->referral_count;i++) { + struct referral* ref = &(junction->referral_list[i]); + int unilen; + + SSVAL(pdata,offset,2); /* version 2 */ + SSVAL(pdata,offset+2,VERSION2_REFERRAL_SIZE); + if(self_referral) + SSVAL(pdata,offset+4,1); + else + SSVAL(pdata,offset+4,0); + SSVAL(pdata,offset+6,0); /* ref_flags :use path_consumed bytes? */ + SIVAL(pdata,offset+8,ref->proximity); + SIVAL(pdata,offset+12,ref->ttl); + + SSVAL(pdata,offset+16,uni_reqpathoffset1-offset); + SSVAL(pdata,offset+18,uni_reqpathoffset2-offset); + /* copy referred path into current offset */ + unilen = (dos_struni2(pdata+uni_curroffset,ref->alternate_path,512) +1)*2; + SSVAL(pdata,offset+20,uni_curroffset-offset); + + uni_curroffset += unilen; + offset += VERSION2_REFERRAL_SIZE; + } + /* add in the unexplained 22 (0x16) bytes at the end */ + memset(pdata+uni_curroffset,'\0',0x16); + free(junction->referral_list); + return reply_size; } static int setup_ver3_dfs_referral(char* pathname, char** ppdata, struct junction_map* junction, BOOL self_referral) { - char* pdata = *ppdata; + char* pdata = *ppdata; - unsigned char uni_reqpath[1024]; - int uni_reqpathoffset1, uni_reqpathoffset2; - int uni_curroffset; - int reply_size = 0; + unsigned char uni_reqpath[1024]; + int uni_reqpathoffset1, uni_reqpathoffset2; + int uni_curroffset; + int reply_size = 0; - int reqpathlen = 0; - int offset,i=0; + int reqpathlen = 0; + int offset,i=0; - DEBUG(10,("setting up version3 referral\n")); + DEBUG(10,("setting up version3 referral\n")); - reqpathlen = (dos_struni2(uni_reqpath,pathname,512)+1)*2; + reqpathlen = (dos_struni2(uni_reqpath,pathname,512)+1)*2; - dump_data(10,uni_reqpath,reqpathlen); - - uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + VERSION3_REFERRAL_SIZE * - junction->referral_count; - uni_reqpathoffset2 = uni_reqpathoffset1 + reqpathlen; - reply_size = uni_curroffset = uni_reqpathoffset2 + reqpathlen; - - for(i=0;i<junction->referral_count;i++) - { - DEBUG(10,("referral %u : %s\n",i,junction->referral_list[i].alternate_path)); - reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2; - } - - pdata = *ppdata = Realloc(pdata,reply_size); - if(pdata == NULL) - { - DEBUG(0,("version3 referral setup: malloc failed for Realloc!\n")); - return -1; - } + dump_data(10,uni_reqpath,reqpathlen); + + uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + VERSION3_REFERRAL_SIZE * junction->referral_count; + uni_reqpathoffset2 = uni_reqpathoffset1 + reqpathlen; + reply_size = uni_curroffset = uni_reqpathoffset2 + reqpathlen; + + for(i=0;i<junction->referral_count;i++) { + DEBUG(10,("referral %u : %s\n",i,junction->referral_list[i].alternate_path)); + reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2; + } + + pdata = *ppdata = Realloc(pdata,reply_size); + if(pdata == NULL) { + DEBUG(0,("version3 referral setup: malloc failed for Realloc!\n")); + return -1; + } - /* create the header */ - SSVAL(pdata,0,reqpathlen-2); /* path consumed */ - SSVAL(pdata,2,junction->referral_count); /* number of referral in this pkt */ - if(self_referral) - SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER); - else - SIVAL(pdata,4,DFSREF_STORAGE_SERVER); + /* create the header */ + SSVAL(pdata,0,reqpathlen-2); /* path consumed */ + SSVAL(pdata,2,junction->referral_count); /* number of referral in this pkt */ + if(self_referral) + SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER); + else + SIVAL(pdata,4,DFSREF_STORAGE_SERVER); - /* copy in the reqpaths */ - memcpy(pdata+uni_reqpathoffset1,uni_reqpath,reqpathlen); - memcpy(pdata+uni_reqpathoffset2,uni_reqpath,reqpathlen); + /* copy in the reqpaths */ + memcpy(pdata+uni_reqpathoffset1,uni_reqpath,reqpathlen); + memcpy(pdata+uni_reqpathoffset2,uni_reqpath,reqpathlen); - offset = 8; - for(i=0;i<junction->referral_count;i++) - { - struct referral* ref = &(junction->referral_list[i]); - int unilen; - - SSVAL(pdata,offset,3); /* version 3 */ - SSVAL(pdata,offset+2,VERSION3_REFERRAL_SIZE); - if(self_referral) - SSVAL(pdata,offset+4,1); - else - SSVAL(pdata,offset+4,0); - - SSVAL(pdata,offset+6,0); /* ref_flags :use path_consumed bytes? */ - SIVAL(pdata,offset+8,ref->ttl); + offset = 8; + for(i=0;i<junction->referral_count;i++) { + struct referral* ref = &(junction->referral_list[i]); + int unilen; + + SSVAL(pdata,offset,3); /* version 3 */ + SSVAL(pdata,offset+2,VERSION3_REFERRAL_SIZE); + if(self_referral) + SSVAL(pdata,offset+4,1); + else + SSVAL(pdata,offset+4,0); + + SSVAL(pdata,offset+6,0); /* ref_flags :use path_consumed bytes? */ + SIVAL(pdata,offset+8,ref->ttl); - SSVAL(pdata,offset+12,uni_reqpathoffset1-offset); - SSVAL(pdata,offset+14,uni_reqpathoffset2-offset); - /* copy referred path into current offset */ - unilen = (dos_struni2(pdata+uni_curroffset,ref->alternate_path,512) - +1)*2; - SSVAL(pdata,offset+16,uni_curroffset-offset); - /* copy 0x10 bytes of 00's in the ServiceSite GUID */ - memset(pdata+offset+18,'\0',16); - - uni_curroffset += unilen; - offset += VERSION3_REFERRAL_SIZE; - } - free(junction->referral_list); - return reply_size; + SSVAL(pdata,offset+12,uni_reqpathoffset1-offset); + SSVAL(pdata,offset+14,uni_reqpathoffset2-offset); + /* copy referred path into current offset */ + unilen = (dos_struni2(pdata+uni_curroffset,ref->alternate_path,512) +1)*2; + SSVAL(pdata,offset+16,uni_curroffset-offset); + /* copy 0x10 bytes of 00's in the ServiceSite GUID */ + memset(pdata+offset+18,'\0',16); + + uni_curroffset += unilen; + offset += VERSION3_REFERRAL_SIZE; + } + free(junction->referral_list); + return reply_size; } - - /****************************************************************** * Set up the Dfs referral for the dfs pathname ******************************************************************/ -int setup_dfs_referral(char* pathname, int max_referral_level, - char** ppdata) + +int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) { - struct junction_map junction; + struct junction_map junction; - BOOL self_referral; + BOOL self_referral; - int reply_size = 0; + int reply_size = 0; - ZERO_STRUCT(junction); + ZERO_STRUCT(junction); - if(!create_junction(pathname, &junction)) - return -1; + if(!create_junction(pathname, &junction)) + return -1; - /* get the junction entry */ - if(!get_referred_path(&junction)) - { + /* get the junction entry */ + if(!get_referred_path(&junction)) { + + /* refer the same pathname, create a standard referral struct */ + struct referral* ref; + self_referral = True; + junction.referral_count = 1; + if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) { + DEBUG(0,("malloc failed for referral\n")); + return -1; + } - /* refer the same pathname, create a standard referral struct */ - struct referral* ref; - self_referral = True; - junction.referral_count = 1; - if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) - { - DEBUG(0,("malloc failed for referral\n")); - return -1; + pstrcpy(ref->alternate_path,pathname); + ref->proximity = 0; + ref->ttl = REFERRAL_TTL; + junction.referral_list = ref; + } else { + self_referral = False; + if( DEBUGLVL( 3 ) ) { + int i=0; + dbgtext("setup_dfs_referral: Path %s to alternate path(s):",pathname); + for(i=0;i<junction.referral_count;i++) + dbgtext(" %s",junction.referral_list[i].alternate_path); + dbgtext(".\n"); + } } - pstrcpy(ref->alternate_path,pathname); - ref->proximity = 0; - ref->ttl = REFERRAL_TTL; - junction.referral_list = ref; - } - else - { - self_referral = False; - if( DEBUGLVL( 3 ) ) - { - int i=0; - dbgtext("setup_dfs_referral: Path %s to alternate path(s):",pathname); - for(i=0;i<junction.referral_count;i++) - dbgtext(" %s",junction.referral_list[i].alternate_path); - dbgtext(".\n"); + /* create the referral depeding on version */ + DEBUG(10,("max_referral_level :%d\n",max_referral_level)); + if(max_referral_level<2 || max_referral_level>3) + max_referral_level = 2; + + switch(max_referral_level) { + case 2: + { + reply_size = setup_ver2_dfs_referral(pathname, ppdata, &junction, self_referral); + break; + } + case 3: + { + reply_size = setup_ver3_dfs_referral(pathname, ppdata, &junction, self_referral); + break; + } + default: + { + DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", max_referral_level)); + return -1; + } } - } - /* create the referral depeding on version */ - DEBUG(10,("max_referral_level :%d\n",max_referral_level)); - if(max_referral_level<2 || max_referral_level>3) max_referral_level = 2; - - switch(max_referral_level) - { - case 2: - { - reply_size = setup_ver2_dfs_referral(pathname, ppdata, &junction, - self_referral); - break; - } - case 3: - { - reply_size = setup_ver3_dfs_referral(pathname, ppdata, &junction, - self_referral); - break; - } - default: - { - DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", - max_referral_level)); - return -1; - } - } - - DEBUG(10,("DFS Referral pdata:\n")); - dump_data(10,*ppdata,reply_size); - return reply_size; + DEBUG(10,("DFS Referral pdata:\n")); + dump_data(10,*ppdata,reply_size); + return reply_size; } int dfs_path_error(char* inbuf, char* outbuf) { - enum remote_arch_types ra_type = get_remote_arch(); - BOOL NT_arch = ((ra_type==RA_WINNT) || (ra_type == RA_WIN2K)); - if(NT_arch && (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32)) ) - { - SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - return(ERROR(0,0xc0000000|NT_STATUS_PATH_NOT_COVERED)); - } - return(ERROR(ERRSRV,ERRbadpath)); + enum remote_arch_types ra_type = get_remote_arch(); + BOOL NT_arch = ((ra_type==RA_WINNT) || (ra_type == RA_WIN2K)); + if(NT_arch && (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32)) ) { + SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); + return(ERROR(0,0xc0000000|NT_STATUS_PATH_NOT_COVERED)); + } + return(ERROR(ERRSRV,ERRbadpath)); } /********************************************************************** The following functions are called by the NETDFS RPC pipe functions **********************************************************************/ + BOOL create_msdfs_link(struct junction_map* jn, BOOL exists) { - pstring path; - pstring msdfs_link; - int i=0; - - if(!form_path_from_junction(jn, path, sizeof(path))) - return False; + pstring path; + pstring msdfs_link; + connection_struct conns; + connection_struct *conn = &conns; + int i=0; + + if(!form_path_from_junction(jn, path, sizeof(path), conn)) + return False; - /* form the msdfs_link contents */ - pstrcpy(msdfs_link, "msdfs:"); - for(i=0; i<jn->referral_count; i++) - { - char* refpath = jn->referral_list[i].alternate_path; + /* form the msdfs_link contents */ + pstrcpy(msdfs_link, "msdfs:"); + for(i=0; i<jn->referral_count; i++) { + char* refpath = jn->referral_list[i].alternate_path; - trim_string(refpath, "\\", "\\"); - if(*refpath == '\0') - continue; + trim_string(refpath, "\\", "\\"); + if(*refpath == '\0') + continue; - if(i>0) - pstrcat(msdfs_link, ","); + if(i>0) + pstrcat(msdfs_link, ","); - pstrcat(msdfs_link, refpath); - } - - DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n", - path, msdfs_link)); - - if(exists) - if(unlink(path)!=0) - return False; - - if(symlink(msdfs_link, path) < 0) - { - DEBUG(1,("create_msdfs_link: symlink failed %s -> %s\nError: %s\n", - path, msdfs_link, strerror(errno))); - return False; - } - return True; + pstrcat(msdfs_link, refpath); + } + + DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n", path, msdfs_link)); + + if(exists) + if(conn->vfs_ops.unlink(conn,path)!=0) + return False; + + if(conn->vfs_ops.symlink(conn, msdfs_link, path) < 0) { + DEBUG(1,("create_msdfs_link: symlink failed %s -> %s\nError: %s\n", + path, msdfs_link, strerror(errno))); + return False; + } + return True; } BOOL remove_msdfs_link(struct junction_map* jn) { - pstring path; + pstring path; + connection_struct conns; + connection_struct *conn = &conns; - if(!form_path_from_junction(jn, path, sizeof(path))) - return False; + if(!form_path_from_junction(jn, path, sizeof(path), conn)) + return False; - if(unlink(path)!=0) - return False; + if(conn->vfs_ops.unlink(conn, path)!=0) + return False; - return True; + return True; } static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) { - int cnt = *jn_count; - DIR *dirp; - char* dname; - - char* connect_path = lp_pathname(snum); - char* service_name = lp_servicename(snum); + int cnt = *jn_count; + DIR *dirp; + char* dname; + pstring connect_path; + char* service_name = lp_servicename(snum); + connection_struct conns; + connection_struct *conn = &conns; - if(*connect_path == '\0') - return False; - - /* form a junction for the msdfs root - convention */ - /* - pstrpcy(jn[cnt].service_name, service_name); - jn[cnt].volume_name[0] = '\0'; - jn[cnt].referral_count = 1; + pstrcpy(connect_path,lp_pathname(snum)); + + if(*connect_path == '\0') + return False; + + /* + * Fake up a connection struct for the VFS layer. + */ + + if (!create_conn_struct(conn, snum, connect_path)) + return False; + + /* form a junction for the msdfs root - convention */ + /* + pstrpcy(jn[cnt].service_name, service_name); + jn[cnt].volume_name[0] = '\0'; + jn[cnt].referral_count = 1; - slprintf(alt_path,sizeof(alt_path)-1"\\\\%s\\%s", global_myname, service_name); - jn[cnt].referral_l - */ - - dirp = opendir(connect_path); - if(!dirp) - return False; - - while((dname = readdirname(dirp)) != NULL) - { - SMB_STRUCT_STAT st; - pstring pathreal; - fstring buf; - int buflen = 0; - pstrcpy(pathreal, connect_path); - pstrcat(pathreal, "/"); - pstrcat(pathreal, dname); + slprintf(alt_path,sizeof(alt_path)-1"\\\\%s\\%s", global_myname, service_name); + jn[cnt].referral_l + */ + + dirp = conn->vfs_ops.opendir(conn, dos_to_unix(connect_path,False)); + if(!dirp) + return False; + + while((dname = vfs_readdirname(conn, dirp)) != NULL) { + SMB_STRUCT_STAT st; + pstring pathreal; + fstring buf; + int buflen = 0; + pstrcpy(pathreal, connect_path); + pstrcat(pathreal, "/"); + pstrcat(pathreal, dname); - if(lstat(pathreal,&st) != 0) - { - DEBUG(4,("lstat error for %s: %s\n",pathreal, strerror(errno))); - continue; + if(conn->vfs_ops.lstat(conn,pathreal,&st) != 0) { + DEBUG(4,("lstat error for %s: %s\n",pathreal, strerror(errno))); + continue; + } + if(S_ISLNK(st.st_mode)) { + buflen = conn->vfs_ops.readlink(conn, dos_to_unix(pathreal,False), buf, sizeof(fstring)); + buf[buflen] = '\0'; + if(parse_symlink(buf, &(jn[cnt].referral_list), &(jn[cnt].referral_count))) { + pstrcpy(jn[cnt].service_name, service_name); + pstrcpy(jn[cnt].volume_name, dname); + cnt++; + } + } } - if(S_ISLNK(st.st_mode)) - { - buflen = readlink(pathreal, buf, sizeof(fstring)); - buf[buflen] = '\0'; - if(parse_symlink(buf, &(jn[cnt].referral_list), - &(jn[cnt].referral_count))) - { - pstrcpy(jn[cnt].service_name, service_name); - pstrcpy(jn[cnt].volume_name, dname); - cnt++; - } - } - } - closedir(dirp); - *jn_count = cnt; - return True; + conn->vfs_ops.closedir(conn,dirp); + *jn_count = cnt; + return True; } int enum_msdfs_links(struct junction_map* jn) { - int i=0; - int jn_count = 0; - - if(!lp_host_msdfs()) - return -1; - - for(i=0;*lp_servicename(i);i++) - { - if(lp_msdfs_root(i)) - form_junctions(i,jn,&jn_count); - } - return jn_count; + int i=0; + int jn_count = 0; + + if(!lp_host_msdfs()) + return -1; + + for(i=0;*lp_servicename(i);i++) { + if(lp_msdfs_root(i)) + form_junctions(i,jn,&jn_count); + } + return jn_count; } #else /* Stub functions if WITH_MSDFS not defined */ -int setup_dfs_referral(char* pathname, int max_referral_level, - char** ppdata) + int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) { - return -1; + return -1; } -BOOL is_msdfs_link(connection_struct* conn, char* path) + BOOL is_msdfs_link(connection_struct* conn, char* path) { - return False; + return False; } #endif diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c index 46f6056e7c0..2fab8f6bc7b 100644 --- a/source/nmbd/nmbd.c +++ b/source/nmbd/nmbd.c @@ -83,7 +83,7 @@ static void sig_term(int sig) /**************************************************************************** ** catch a sighup **************************************************************************** */ -static VOLATILE SIG_ATOMIC_T reload_after_sighup = False; +static VOLATILE sig_atomic_t reload_after_sighup = False; static void sig_hup(int sig) { @@ -460,7 +460,9 @@ static void process(void) * This will only work to a Samba WINS server. * (nmbd_browsesync.c) */ - collect_all_workgroup_names_from_wins_server(t); + if (lp_enhanced_browsing()) { + collect_all_workgroup_names_from_wins_server(t); + } /* * Go through the response record queue and time out or re-transmit @@ -477,7 +479,9 @@ static void process(void) /* * regularly sync with any other DMBs we know about */ - sync_all_dmbs(t); + if (lp_enhanced_browsing()) { + sync_all_dmbs(t); + } /* * clear the unexpected packet queue diff --git a/source/nmbd/nmbd_namequery.c b/source/nmbd/nmbd_namequery.c index 57baa4cb2f0..61435c14f55 100644 --- a/source/nmbd/nmbd_namequery.c +++ b/source/nmbd/nmbd_namequery.c @@ -30,8 +30,9 @@ extern int DEBUGLEVEL; Deal with a response packet when querying a name. ****************************************************************************/ -static void query_name_response(struct subnet_record *subrec, - struct response_record *rrec, struct packet_struct *p) +static void query_name_response( struct subnet_record *subrec, + struct response_record *rrec, + struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; BOOL success = False; @@ -52,9 +53,14 @@ static void query_name_response(struct subnet_record *subrec, { /* WINS server is telling us to wait. Pretend we didn't get the response but don't send out any more query requests. */ - - DEBUG(5,("query_name_response: WACK from WINS server %s in querying \ -name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(question_name), subrec->subnet_name)); + + if( DEBUGLVL( 5 ) ) + { + dbgtext( "query_name_response: " ); + dbgtext( "WACK from WINS server %s ", inet_ntoa(p->ip) ); + dbgtext( "in querying name %s ", nmb_namestr(question_name) ); + dbgtext( "on subnet %s.\n", subrec->subnet_name ); + } rrec->repeat_count = 0; /* How long we should wait for. */ @@ -66,18 +72,26 @@ name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(question_name), subrec-> { success = False; - DEBUG(5,("query_name_response: On subnet %s - negative response \ -from IP %s for name %s. Error code was %d.\n", subrec->subnet_name, inet_ntoa(p->ip), - nmb_namestr(question_name), nmb->header.rcode)); + if( DEBUGLVL( 5 ) ) + { + dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name ); + dbgtext( "- negative response from IP %s ", inet_ntoa(p->ip) ); + dbgtext( "for name %s. ", nmb_namestr(question_name) ); + dbgtext( "Error code was %d.\n", nmb->header.rcode ); + } } else { success = True; putip((char *)&answer_ip,&nmb->answers->rdata[2]); - DEBUG(5,("query_name_response: On subnet %s - positive response from IP %s \ -for name %s. IP of that name is %s\n", subrec->subnet_name, inet_ntoa(p->ip), - nmb_namestr(question_name), inet_ntoa(answer_ip))); + if( DEBUGLVL( 5 ) ) + { + dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name ); + dbgtext( "- positive response from IP %s ", inet_ntoa(p->ip) ); + dbgtext( "for name %s. ", nmb_namestr(question_name) ); + dbgtext( "IP of that name is %s\n", inet_ntoa(answer_ip) ); + } /* Interestingly, we could add these names to our namelists, and change nmbd to a model that checked its own name cache first, @@ -87,10 +101,15 @@ for name %s. IP of that name is %s\n", subrec->subnet_name, inet_ntoa(p->ip), } else if( rrec->num_msgs > 1) { - DEBUG(0,("query_name_response: Multiple (%d) responses received for a query on \ -subnet %s for name %s. This response was from IP %s\n", - rrec->num_msgs, subrec->subnet_name, nmb_namestr(question_name), - inet_ntoa(p->ip) )); + if( DEBUGLVL( 0 ) ) + { + dbgtext( "query_name_response: " ); + dbgtext( "Multiple (%d) responses ", rrec->num_msgs ); + dbgtext( "received for a query on subnet %s ", subrec->subnet_name ); + dbgtext( "for name %s.\nThis response ", nmb_namestr(question_name) ); + dbgtext( "was from IP %s, reporting", inet_ntoa(p->ip) ); + dbgtext( "an IP address of %s.\n", inet_ntoa(answer_ip) ); + } /* We have already called the success or fail function, so we don't call again here. Leave the response record around in @@ -128,9 +147,12 @@ static void query_name_timeout_response(struct subnet_record *subrec, if(failed) { - DEBUG(5,("query_name_timeout_response: No response to querying name %s on subnet %s.\n", - nmb_namestr(question_name), subrec->subnet_name)); - + if( DEBUGLVL( 5 ) ) + { + dbgtext( "query_name_timeout_response: No response to " ); + dbgtext( "query for name %s ", nmb_namestr(question_name) ); + dbgtext( "on subnet %s.\n", subrec->subnet_name ); + } if(rrec->fail_fn) (*rrec->fail_fn)(subrec, rrec, question_name, 0); } @@ -201,8 +223,12 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type, rrec.rdlength = namerec->data.num_ips * 6; if(rrec.rdlength > MAX_DGRAM_SIZE) { - DEBUG(0,("query_name: nmbd internal error - there are %d ip addresses for name %s.\n", - namerec->data.num_ips, nmb_namestr(&nmbname) )); + if( DEBUGLVL( 0 ) ) + { + dbgtext( "query_name: nmbd internal error - " ); + dbgtext( "there are %d ip addresses ", namerec->data.num_ips ); + dbgtext( "for name %s.\n", nmb_namestr(&nmbname) ); + } return False; } @@ -226,8 +252,11 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type, userdata, &nmbname) == NULL) { - DEBUG(0,("query_name: Failed to send packet trying to query name %s\n", - nmb_namestr(&nmbname))); + if( DEBUGLVL( 0 ) ) + { + dbgtext( "query_name: Failed to send packet " ); + dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) ); + } return True; } return False; @@ -255,8 +284,11 @@ BOOL query_name_from_wins_server(struct in_addr ip_to, userdata, &nmbname) == NULL) { - DEBUG(0,("query_name_from_wins_server: Failed to send packet trying to query name %s\n", - nmb_namestr(&nmbname))); + if( DEBUGLVL( 0 ) ) + { + dbgtext( "query_name_from_wins_server: Failed to send packet " ); + dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) ); + } return True; } return False; diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c index 8b102985611..00059c1775e 100644 --- a/source/nmbd/nmbd_packets.c +++ b/source/nmbd/nmbd_packets.c @@ -107,12 +107,14 @@ static void debug_browse_data(char *outbuf, int len) for (j = 0; j < 16; j++) { - unsigned char x = outbuf[i+j]; + unsigned char x; + if (i+j >= len) + break; + + x = outbuf[i+j]; if (x < 32 || x > 127) x = '.'; - if (i+j >= len) - break; DEBUGADD( 4, ( "%c", x ) ); } @@ -1263,14 +1265,21 @@ an error packet of type %x\n", len = SVAL(buf,smb_vwv11); buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); + if (len <= 0) + return; + + if (buf2 + len > buf + sizeof(dgram->data)) { + DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n", + nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name), + inet_ntoa(p->ip), smb_buf(buf),len)); + len = (buf + sizeof(dgram->data)) - buf; + } + DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n", nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len)); - if (len <= 0) - return; - /* Datagram packet received for the browser mailslot */ if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) { diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c index 6105fb41650..23cbc01b889 100644 --- a/source/nmbd/nmbd_synclists.c +++ b/source/nmbd/nmbd_synclists.c @@ -51,7 +51,8 @@ static FILE *fp; This is the NetServerEnum callback. Note sname and comment are in UNIX codepage format. ******************************************************************/ -static void callback(const char *sname, uint32 stype, const char *comment) +static void callback(const char *sname, uint32 stype, + const char *comment, void *state) { fprintf(fp,"\"%s\" %08X \"%s\"\n", sname, stype, comment); } @@ -106,8 +107,8 @@ static void sync_child(char *name, int nm_type, /* Fetch a workgroup list. */ cli_NetServerEnum(&cli, unix_workgroup, - local_type|SV_TYPE_DOMAIN_ENUM, - callback); + local_type|SV_TYPE_DOMAIN_ENUM, + callback, NULL); /* Now fetch a server list. */ if (servers) { @@ -115,7 +116,7 @@ static void sync_child(char *name, int nm_type, dos_to_unix(unix_workgroup, True); cli_NetServerEnum(&cli, unix_workgroup, local?SV_TYPE_LOCAL_LIST_ONLY:SV_TYPE_ALL, - callback); + callback, NULL); } cli_shutdown(&cli); diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c index ece504411b3..a8410f85086 100644 --- a/source/nsswitch/pam_winbind.c +++ b/source/nsswitch/pam_winbind.c @@ -19,8 +19,12 @@ #define MODULE_NAME "pam_winbind" #define PAM_SM_AUTH #define PAM_SM_ACCOUNT +#ifdef HAVE_SECURITY_PAM_MODULES_H #include <security/pam_modules.h> +#endif +#ifdef HAVE_SECURITY__PAM_MACROS_H #include <security/_pam_macros.h> +#endif #define PAM_DEBUG_ARG (1<<0) #define PAM_USE_AUTHTOK_ARG (1<<1) diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c index 746e5406bc8..71a21a97207 100644 --- a/source/nsswitch/wb_client.c +++ b/source/nsswitch/wb_client.c @@ -31,7 +31,7 @@ BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name { struct winbindd_request request; struct winbindd_response response; - enum nss_status result; + NSS_STATUS result; if (!sid || !name_type) return False; @@ -42,7 +42,7 @@ BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name ZERO_STRUCT(response); fstrcpy(request.data.name, name); - if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request, + if ((result = (NSS_STATUS)winbindd_request(WINBINDD_LOOKUPNAME, &request, &response)) == NSS_STATUS_SUCCESS) { string_to_sid(sid, response.data.sid.sid); *name_type = (enum SID_NAME_USE)response.data.sid.type; @@ -57,7 +57,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N { struct winbindd_request request; struct winbindd_response response; - enum nss_status result; + NSS_STATUS result; fstring sid_str; /* Initialise request */ @@ -70,7 +70,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N /* Make request */ - result = winbindd_request(WINBINDD_LOOKUPSID, &request, &response); + result = (NSS_STATUS)winbindd_request(WINBINDD_LOOKUPSID, &request, &response); /* Copy out result */ diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c index 98a4b6758bc..243f05825b7 100644 --- a/source/nsswitch/wb_common.c +++ b/source/nsswitch/wb_common.c @@ -59,7 +59,7 @@ void init_response(struct winbindd_response *response) { /* Initialise return value */ - response->result = (enum winbindd_result)NSS_STATUS_UNAVAIL; + response->result = WINBINDD_ERROR; } /* Close established socket */ @@ -141,6 +141,7 @@ static int open_pipe_sock(void) if (connect(established_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { close_sock(); + established_socket = -1; return -1; } @@ -304,7 +305,7 @@ void free_response(struct winbindd_response *response) /* Handle simple types of requests */ -enum nss_status winbindd_request(int req_type, +NSS_STATUS winbindd_request(int req_type, struct winbindd_request *request, struct winbindd_response *response) { diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c index cff2b8b69a0..f20e1b16144 100644 --- a/source/nsswitch/wbinfo.c +++ b/source/nsswitch/wbinfo.c @@ -28,7 +28,7 @@ /* Prototypes from common.h - only needed #if TNG */ -enum nss_status winbindd_request(int req_type, +NSS_STATUS winbindd_request(int req_type, struct winbindd_request *request, struct winbindd_response *response); @@ -101,10 +101,11 @@ static BOOL wbinfo_check_secret(void) if (result) { - if (response.data.num_entries) { + if (response.data.num_entries == 0) { printf("Secret is good\n"); } else { - printf("Secret is bad\n"); + printf("Secret is bad\n0x%08x\n", + response.data.num_entries); } return True; @@ -447,8 +448,8 @@ int main(int argc, char **argv) return 1; } break; - - /* Invalid option */ + + /* Invalid option */ default: usage(); diff --git a/source/nsswitch/winbind_nss.c b/source/nsswitch/winbind_nss.c index 78485aa05e3..04b576a7a53 100644 --- a/source/nsswitch/winbind_nss.c +++ b/source/nsswitch/winbind_nss.c @@ -25,11 +25,15 @@ #include "winbind_nss_config.h" #include "winbindd_nss.h" -/* prototypes from common.c */ +/* Prototypes from common.c */ + void init_request(struct winbindd_request *req,int rq_type); +NSS_STATUS winbindd_request(int req_type, + struct winbindd_request *request, + struct winbindd_response *response); int write_sock(void *buffer, int count); int read_reply(struct winbindd_response *response); - +void free_response(struct winbindd_response *response); /* Allocate some space from the nss static buffer. The buffer and buflen are the pointers passed in by the C library to the _nss_ntdom_* @@ -37,429 +41,810 @@ int read_reply(struct winbindd_response *response); static char *get_static(char **buffer, int *buflen, int len) { - char *result; + char *result; - /* Error check. We return false if things aren't set up right, or - there isn't enough buffer space left. */ + /* Error check. We return false if things aren't set up right, or + there isn't enough buffer space left. */ + + if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) { + return NULL; + } - if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) { - return NULL; - } + /* Some architectures, like Sparc, need pointers aligned on + boundaries */ +#if _ALIGNMENT_REQUIRED + { + int mod = len % _MAX_ALIGNMENT; + if(mod != 0) + len += _MAX_ALIGNMENT - mod; + } +#endif - /* Return an index into the static buffer */ + /* Return an index into the static buffer */ - result = *buffer; - *buffer += len; - *buflen -= len; + result = *buffer; + *buffer += len; + *buflen -= len; - return result; + return result; } /* I've copied the strtok() replacement function next_token() from lib/util_str.c as I really don't want to have to link in any other objects if I can possibly avoid it. */ -#ifdef strchr /* Aargh! This points at multibyte_strchr(). )-: */ -#undef strchr -#endif - static char *last_ptr = NULL; BOOL next_token(char **ptr, char *buff, char *sep, size_t bufsize) { - char *s; - BOOL quoted; - size_t len=1; + char *s; + BOOL quoted; + size_t len=1; - if (!ptr) ptr = &last_ptr; - if (!ptr) return(False); + if (!ptr) ptr = &last_ptr; + if (!ptr) return(False); - s = *ptr; + s = *ptr; - /* default to simple separators */ - if (!sep) sep = " \t\n\r"; + /* default to simple separators */ + if (!sep) sep = " \t\n\r"; - /* find the first non sep char */ - while(*s && strchr(sep,*s)) s++; + /* find the first non sep char */ + while(*s && strchr(sep,*s)) s++; - /* nothing left? */ - if (! *s) return(False); + /* 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; - } - } + /* 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; - last_ptr = *ptr; + *ptr = (*s) ? s+1 : s; + *buff = 0; + last_ptr = *ptr; - return(True); -} - - -/* handle simple types of requests */ -static enum nss_status generic_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response) -{ - struct winbindd_request lrequest; - struct winbindd_response lresponse; - - if (!response) response = &lresponse; - if (!request) request = &lrequest; - - /* Fill in request and send down pipe */ - init_request(request, req_type); - - if (write_sock(request, sizeof(*request)) == -1) { - return NSS_STATUS_UNAVAIL; - } - - /* Wait for reply */ - if (read_reply(response) == -1) { - return NSS_STATUS_UNAVAIL; - } - - /* Copy reply data from socket */ - if (response->result != WINBINDD_OK) { - return NSS_STATUS_NOTFOUND; - } - - return NSS_STATUS_SUCCESS; + return(True); } /* Fill a pwent structure from a winbindd_response structure. We use the static data passed to us by libc to put strings and stuff in. - Return errno = ERANGE and NSS_STATUS_TRYAGAIN if we run out of - memory. */ + Return NSS_STATUS_TRYAGAIN if we run out of memory. */ -static enum nss_status fill_pwent(struct passwd *result, - struct winbindd_response *response, - char **buffer, int *buflen, int *errnop) +static NSS_STATUS fill_pwent(struct passwd *result, + struct winbindd_pw *pw, + char **buffer, int *buflen) { - struct winbindd_pw *pw = &response->data.pw; - - /* User name */ + /* User name */ - if ((result->pw_name = - get_static(buffer, buflen, strlen(pw->pw_name) + 1)) == NULL) { + if ((result->pw_name = + get_static(buffer, buflen, strlen(pw->pw_name) + 1)) == NULL) { - /* Out of memory */ + /* Out of memory */ - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + return NSS_STATUS_TRYAGAIN; + } - strcpy(result->pw_name, pw->pw_name); + strcpy(result->pw_name, pw->pw_name); - /* Password */ + /* Password */ - if ((result->pw_passwd = - get_static(buffer, buflen, strlen(pw->pw_passwd) + 1)) == NULL) { + if ((result->pw_passwd = + get_static(buffer, buflen, strlen(pw->pw_passwd) + 1)) == NULL) { - /* Out of memory */ + /* Out of memory */ - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + return NSS_STATUS_TRYAGAIN; + } - strcpy(result->pw_passwd, pw->pw_passwd); + strcpy(result->pw_passwd, pw->pw_passwd); - /* [ug]id */ - - result->pw_uid = pw->pw_uid; - result->pw_gid = pw->pw_gid; - - /* GECOS */ + /* [ug]id */ - if ((result->pw_gecos = - get_static(buffer, buflen, strlen(pw->pw_gecos) + 1)) == NULL) { + result->pw_uid = pw->pw_uid; + result->pw_gid = pw->pw_gid; - /* Out of memory */ + /* GECOS */ - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + if ((result->pw_gecos = + get_static(buffer, buflen, strlen(pw->pw_gecos) + 1)) == NULL) { - strcpy(result->pw_gecos, pw->pw_gecos); + /* Out of memory */ - /* Home directory */ - - if ((result->pw_dir = - get_static(buffer, buflen, strlen(pw->pw_dir) + 1)) == NULL) { - - /* Out of memory */ + return NSS_STATUS_TRYAGAIN; + } - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + strcpy(result->pw_gecos, pw->pw_gecos); + + /* Home directory */ + + if ((result->pw_dir = + get_static(buffer, buflen, strlen(pw->pw_dir) + 1)) == NULL) { - strcpy(result->pw_dir, pw->pw_dir); + /* Out of memory */ - /* Logon shell */ + return NSS_STATUS_TRYAGAIN; + } - if ((result->pw_shell = - get_static(buffer, buflen, strlen(pw->pw_shell) + 1)) == NULL) { + strcpy(result->pw_dir, pw->pw_dir); - /* Out of memory */ + /* Logon shell */ + + if ((result->pw_shell = + get_static(buffer, buflen, strlen(pw->pw_shell) + 1)) == NULL) { + + /* Out of memory */ - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + return NSS_STATUS_TRYAGAIN; + } - strcpy(result->pw_shell, pw->pw_shell); + strcpy(result->pw_shell, pw->pw_shell); - return NSS_STATUS_SUCCESS; + return NSS_STATUS_SUCCESS; } /* Fill a grent structure from a winbindd_response structure. We use the static data passed to us by libc to put strings and stuff in. - Return errno = ERANGE and NSS_STATUS_TRYAGAIN if we run out of - memory. */ + Return NSS_STATUS_TRYAGAIN if we run out of memory. */ -static int fill_grent(struct group *result, - struct winbindd_response *response, - char **buffer, int *buflen, int *errnop) +static int fill_grent(struct group *result, struct winbindd_gr *gr, + char *gr_mem, char **buffer, int *buflen) { - struct winbindd_gr *gr = &response->data.gr; - fstring name; - int i; + fstring name; + int i; - /* Group name */ + /* Group name */ - if ((result->gr_name = - get_static(buffer, buflen, strlen(gr->gr_name) + 1)) == NULL) { + if ((result->gr_name = + get_static(buffer, buflen, strlen(gr->gr_name) + 1)) == NULL) { - /* Out of memory */ + /* Out of memory */ - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } - - strcpy(result->gr_name, gr->gr_name); + return NSS_STATUS_TRYAGAIN; + } - /* Password */ + strcpy(result->gr_name, gr->gr_name); - if ((result->gr_passwd = - get_static(buffer, buflen, strlen(gr->gr_passwd) + 1)) == NULL) { + /* Password */ - /* Out of memory */ + if ((result->gr_passwd = + get_static(buffer, buflen, strlen(gr->gr_passwd) + 1)) == NULL) { - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + /* Out of memory */ + + return NSS_STATUS_TRYAGAIN; + } - strcpy(result->gr_passwd, gr->gr_passwd); + strcpy(result->gr_passwd, gr->gr_passwd); - /* gid */ + /* gid */ - result->gr_gid = gr->gr_gid; + result->gr_gid = gr->gr_gid; - /* Group membership */ + /* Group membership */ - if ((gr->num_gr_mem < 0) || !response->extra_data) { - gr->num_gr_mem = 0; - } + if ((gr->num_gr_mem < 0) || !gr_mem) { + gr->num_gr_mem = 0; + } - if ((result->gr_mem = - (char **)get_static(buffer, buflen, (gr->num_gr_mem + 1) * - sizeof(char *))) == NULL) { + if ((result->gr_mem = + (char **)get_static(buffer, buflen, (gr->num_gr_mem + 1) * + sizeof(char *))) == NULL) { - /* Out of memory */ + /* Out of memory */ - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + return NSS_STATUS_TRYAGAIN; + } - if (gr->num_gr_mem == 0) { + if (gr->num_gr_mem == 0) { - /* Group is empty */ + /* Group is empty */ - *(result->gr_mem) = NULL; - return NSS_STATUS_SUCCESS; - } + *(result->gr_mem) = NULL; + return NSS_STATUS_SUCCESS; + } - /* Start looking at extra data */ + /* Start looking at extra data */ - i = 0; + i = 0; - while(next_token(&response->extra_data, name, ",", sizeof(fstring))) { + while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) { - /* Allocate space for member */ + /* Allocate space for member */ - if (((result->gr_mem)[i] = - get_static(buffer, buflen, strlen(name) + 1)) == NULL) { + if (((result->gr_mem)[i] = + get_static(buffer, buflen, strlen(name) + 1)) == NULL) { - /* Out of memory */ + /* Out of memory */ - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + return NSS_STATUS_TRYAGAIN; + } - strcpy((result->gr_mem)[i], name); - i++; - } + strcpy((result->gr_mem)[i], name); + i++; + } - /* Terminate list */ + /* Terminate list */ - (result->gr_mem)[i] = NULL; - - return NSS_STATUS_SUCCESS; + (result->gr_mem)[i] = NULL; + + return NSS_STATUS_SUCCESS; } /* * NSS user functions */ +static struct winbindd_response getpwent_response; + +static int ndx_pw_cache; /* Current index into pwd cache */ +static int num_pw_cache; /* Current size of pwd cache */ + /* Rewind "file pointer" to start of ntdom password database */ -enum nss_status +NSS_STATUS _nss_winbind_setpwent(void) { - return generic_request(WINBINDD_SETPWENT, NULL, NULL); +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: setpwent\n", getpid()); +#endif + + if (num_pw_cache > 0) { + ndx_pw_cache = num_pw_cache = 0; + free_response(&getpwent_response); + } + + return winbindd_request(WINBINDD_SETPWENT, NULL, NULL); } /* Close ntdom password database "file pointer" */ -enum nss_status +NSS_STATUS _nss_winbind_endpwent(void) { - return generic_request(WINBINDD_ENDPWENT, NULL, NULL); +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: endpwent\n", getpid()); +#endif + + if (num_pw_cache > 0) { + ndx_pw_cache = num_pw_cache = 0; + free_response(&getpwent_response); + } + + return winbindd_request(WINBINDD_ENDPWENT, NULL, NULL); } /* Fetch the next password entry from ntdom password database */ -enum nss_status +#define MAX_GETPWENT_USERS 250 + +NSS_STATUS _nss_winbind_getpwent_r(struct passwd *result, char *buffer, - size_t buflen, int *errnop) + size_t buflen, int *errnop) { - enum nss_status ret; - struct winbindd_response response; + NSS_STATUS ret; + struct winbindd_request request; + static int called_again; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getpwent\n", getpid()); +#endif + + /* Return an entry from the cache if we have one, or if we are + called again because we exceeded our static buffer. */ + + if ((ndx_pw_cache < num_pw_cache) || called_again) { + goto return_result; + } + + /* Else call winbindd to get a bunch of entries */ + + if (num_pw_cache > 0) { + free_response(&getpwent_response); + } + + ZERO_STRUCT(request); + ZERO_STRUCT(getpwent_response); + + request.data.num_entries = MAX_GETPWENT_USERS; + + ret = winbindd_request(WINBINDD_GETPWENT, &request, + &getpwent_response); + + if (ret == NSS_STATUS_SUCCESS) { + struct winbindd_pw *pw_cache; + + /* Fill cache */ + + ndx_pw_cache = 0; + num_pw_cache = getpwent_response.data.num_entries; - ret = generic_request(WINBINDD_GETPWENT, NULL, &response); - if (ret != NSS_STATUS_SUCCESS) return ret; + /* Return a result */ - return fill_pwent(result, &response, &buffer, &buflen, errnop); + return_result: + + pw_cache = getpwent_response.extra_data; + + /* Check data is valid */ + + if (pw_cache == NULL) { + return NSS_STATUS_NOTFOUND; + } + + ret = fill_pwent(result, &pw_cache[ndx_pw_cache], + &buffer, &buflen); + + /* Out of memory - try again */ + + if (ret == NSS_STATUS_TRYAGAIN) { + called_again = True; + *errnop = errno = ERANGE; + return ret; + } + + *errnop = errno = 0; + called_again = False; + ndx_pw_cache++; + + /* If we've finished with this lot of results free cache */ + + if (ndx_pw_cache == num_pw_cache) { + ndx_pw_cache = num_pw_cache = 0; + free_response(&getpwent_response); + } + } + + return ret; } /* Return passwd struct from uid */ -enum nss_status +NSS_STATUS _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, - size_t buflen, int *errnop) + size_t buflen, int *errnop) { - enum nss_status ret; - struct winbindd_response response; + NSS_STATUS ret; + static struct winbindd_response response; struct winbindd_request request; + static int keep_response=0; + + /* If our static buffer needs to be expanded we are called again */ + if (!keep_response) { - request.data.uid = uid; + /* Call for the first time */ - ret = generic_request(WINBINDD_GETPWNAM_FROM_UID, &request, &response); - if (ret != NSS_STATUS_SUCCESS) return ret; + ZERO_STRUCT(response); + ZERO_STRUCT(request); - return fill_pwent(result, &response, &buffer, &buflen, errnop); + request.data.uid = uid; + + ret = winbindd_request(WINBINDD_GETPWNAM_FROM_UID, &request, + &response); + + if (ret == NSS_STATUS_SUCCESS) { + ret = fill_pwent(result, &response.data.pw, + &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_pwent(result, &response.data.pw, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = errno = 0; + } + + free_response(&response); + return ret; } /* Return passwd struct from username */ -enum nss_status +NSS_STATUS _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer, - size_t buflen, int *errnop) + size_t buflen, int *errnop) { - enum nss_status ret; - struct winbindd_response response; + NSS_STATUS ret; + static struct winbindd_response response; struct winbindd_request request; + static int keep_response; - strncpy(request.data.username, name, sizeof(request.data.username) - 1); - request.data.username[sizeof(request.data.username) - 1] = '\0'; +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getpwnam %s\n", getpid(), name); +#endif - ret = generic_request(WINBINDD_GETPWNAM_FROM_USER, &request, &response); - if (ret != NSS_STATUS_SUCCESS) return ret; + /* If our static buffer needs to be expanded we are called again */ - return fill_pwent(result, &response, &buffer, &buflen, errnop); + if (!keep_response) { + + /* Call for the first time */ + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + strncpy(request.data.username, name, + sizeof(request.data.username) - 1); + request.data.username + [sizeof(request.data.username) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_GETPWNAM_FROM_USER, &request, + &response); + + if (ret == NSS_STATUS_SUCCESS) { + ret = fill_pwent(result, &response.data.pw, &buffer, + &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_pwent(result, &response.data.pw, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = errno = 0; + } + + free_response(&response); + return ret; } /* * NSS group functions */ +static struct winbindd_response getgrent_response; + +static int ndx_gr_cache; /* Current index into grp cache */ +static int num_gr_cache; /* Current size of grp cache */ + /* Rewind "file pointer" to start of ntdom group database */ -enum nss_status +NSS_STATUS _nss_winbind_setgrent(void) { - return generic_request(WINBINDD_SETGRENT, NULL, NULL); +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: setgrent\n", getpid()); +#endif + + if (num_gr_cache > 0) { + ndx_gr_cache = num_gr_cache = 0; + free_response(&getgrent_response); + } + + return winbindd_request(WINBINDD_SETGRENT, NULL, NULL); } /* Close "file pointer" for ntdom group database */ -enum nss_status +NSS_STATUS _nss_winbind_endgrent(void) { - return generic_request(WINBINDD_ENDGRENT, NULL, NULL); -} +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: endgrent\n", getpid()); +#endif + if (num_gr_cache > 0) { + ndx_gr_cache = num_gr_cache = 0; + free_response(&getgrent_response); + } + return winbindd_request(WINBINDD_ENDGRENT, NULL, NULL); +} /* Get next entry from ntdom group database */ -enum nss_status +#define MAX_GETGRENT_USERS 250 + +NSS_STATUS _nss_winbind_getgrent_r(struct group *result, - char *buffer, size_t buflen, int *errnop) + char *buffer, size_t buflen, int *errnop) { - enum nss_status ret; - struct winbindd_response response; + NSS_STATUS ret; + static struct winbindd_request request; + static int called_again; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getgrent\n", getpid()); +#endif + + /* Return an entry from the cache if we have one, or if we are + called again because we exceeded our static buffer. */ + + if ((ndx_gr_cache < num_gr_cache) || called_again) { + goto return_result; + } + + /* Else call winbindd to get a bunch of entries */ + + if (num_gr_cache > 0) { + free_response(&getgrent_response); + } + + ZERO_STRUCT(request); + ZERO_STRUCT(getgrent_response); + + request.data.num_entries = MAX_GETGRENT_USERS; + + ret = winbindd_request(WINBINDD_GETGRENT, &request, + &getgrent_response); + + if (ret == NSS_STATUS_SUCCESS) { + struct winbindd_gr *gr_cache; + int mem_ofs; + + /* Fill cache */ + + ndx_gr_cache = 0; + num_gr_cache = getgrent_response.data.num_entries; + + /* Return a result */ + + return_result: + + gr_cache = getgrent_response.extra_data; + + /* Check data is valid */ + + if (gr_cache == NULL) { + return NSS_STATUS_NOTFOUND; + } + + /* Fill group membership. The offset into the extra data + for the group membership is the reported offset plus the + size of all the winbindd_gr records returned. */ + + mem_ofs = gr_cache[ndx_gr_cache].gr_mem_ofs + + num_gr_cache * sizeof(struct winbindd_gr); + + ret = fill_grent(result, &gr_cache[ndx_gr_cache], + (char *)(getgrent_response.extra_data + + mem_ofs), &buffer, &buflen); + + /* Out of memory - try again */ + + if (ret == NSS_STATUS_TRYAGAIN) { + called_again = True; + *errnop = errno = ERANGE; + return ret; + } + + *errnop = 0; + called_again = False; + ndx_gr_cache++; - ret = generic_request(WINBINDD_GETGRENT, NULL, &response); - if (ret != NSS_STATUS_SUCCESS) return ret; + /* If we've finished with this lot of results free cache */ - return fill_grent(result, &response, &buffer, &buflen, errnop); + if (ndx_gr_cache == num_gr_cache) { + ndx_gr_cache = num_gr_cache = 0; + free_response(&getgrent_response); + } + } + + return ret; } /* Return group struct from group name */ -enum nss_status +NSS_STATUS _nss_winbind_getgrnam_r(const char *name, - struct group *result, char *buffer, - size_t buflen, int *errnop) + struct group *result, char *buffer, + size_t buflen, int *errnop) { - enum nss_status ret; - struct winbindd_response response; + NSS_STATUS ret; + static struct winbindd_response response; struct winbindd_request request; + static int keep_response; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name); +#endif - strncpy(request.data.groupname, name, sizeof(request.data.groupname)); - request.data.groupname[sizeof(request.data.groupname) - 1] = '\0'; - - ret = generic_request(WINBINDD_GETGRNAM_FROM_GROUP, &request, &response); - if (ret != NSS_STATUS_SUCCESS) return ret; + /* If our static buffer needs to be expanded we are called again */ + + if (!keep_response) { + + /* Call for the first time */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.groupname, name, + sizeof(request.data.groupname)); + request.data.groupname + [sizeof(request.data.groupname) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_GETGRNAM_FROM_GROUP, + &request, &response); + + if (ret == NSS_STATUS_SUCCESS) { + ret = fill_grent(result, &response.data.gr, + response.extra_data, + &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_grent(result, &response.data.gr, + response.extra_data, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = 0; + } - return fill_grent(result, &response, &buffer, &buflen, errnop); + free_response(&response); + return ret; } /* Return group struct from gid */ -enum nss_status +NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, - struct group *result, char *buffer, - size_t buflen, int *errnop) + struct group *result, char *buffer, + size_t buflen, int *errnop) { - enum nss_status ret; - struct winbindd_response response; + NSS_STATUS ret; + static struct winbindd_response response; + struct winbindd_request request; + static int keep_response; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid); +#endif + + /* If our static buffer needs to be expanded we are called again */ + + if (!keep_response) { + + /* Call for the first time */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + request.data.gid = gid; + + ret = winbindd_request(WINBINDD_GETGRNAM_FROM_GID, &request, + &response); + + if (ret == NSS_STATUS_SUCCESS) { + + ret = fill_grent(result, &response.data.gr, + response.extra_data, + &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + } + + } else { + + /* We've been called again */ + + ret = fill_grent(result, &response.data.gr, + response.extra_data, &buffer, &buflen); + + if (ret == NSS_STATUS_TRYAGAIN) { + keep_response = True; + *errnop = errno = ERANGE; + return ret; + } + + keep_response = False; + *errnop = 0; + } + + free_response(&response); + return ret; +} + +/* Initialise supplementary groups */ + +NSS_STATUS +_nss_winbind_initgroups(char *user, gid_t group, long int *start, + long int *size, gid_t *groups, long int limit, + int *errnop) +{ + NSS_STATUS ret; struct winbindd_request request; + struct winbindd_response response; + int i; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: initgroups %s (%d)\n", getpid(), + user, group); +#endif + + ZERO_STRUCT(request); + ZERO_STRUCT(response); - request.data.gid = gid; + strncpy(request.data.username, user, + sizeof(request.data.username) - 1); - ret = generic_request(WINBINDD_GETGRNAM_FROM_GID, &request, &response); - if (ret != NSS_STATUS_SUCCESS) return ret; + ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response); + + if (ret == NSS_STATUS_SUCCESS) { + int num_gids = response.data.num_entries; + gid_t *gid_list = (gid_t *)response.extra_data; + + /* Copy group list to client */ + + for (i = 0; i < num_gids; i++) { + + /* Skip primary group */ + + if (gid_list[i] == group) continue; + + /* Add to buffer */ + + if (*start == *size && limit <= 0) { + groups = realloc( + groups, 2 * (*size) * sizeof(*groups)); + if (!groups) goto done; + *size *= 2; + } + + groups[*start] = gid_list[i]; + *start += 1; + + /* Filled buffer? */ + + if (*start == limit) goto done; + } + } + + /* Back to your regularly scheduled programming */ - return fill_grent(result, &response, &buffer, &buflen, errnop); + done: + return ret; } diff --git a/source/nsswitch/winbind_nss_config.h b/source/nsswitch/winbind_nss_config.h index c663842a815..5c09a5dd1bc 100644 --- a/source/nsswitch/winbind_nss_config.h +++ b/source/nsswitch/winbind_nss_config.h @@ -70,17 +70,62 @@ #include <errno.h> #include <pwd.h> -#ifdef HAVE_NSS_H +#ifdef HAVE_NSS_COMMON_H +/* Sun Solaris */ + +#include <nss_common.h> +#include <nss_dbdefs.h> +#include <nsswitch.h> + +typedef nss_status_t NSS_STATUS; + +#define NSS_STATUS_SUCCESS NSS_SUCCESS +#define NSS_STATUS_NOTFOUND NSS_NOTFOUND +#define NSS_STATUS_UNAVAIL NSS_UNAVAIL +#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN + +#elif HAVE_NSS_H +/* GNU */ + #include <nss.h> -#else -/* Minimal needed to compile.. */ -enum nss_status { -NSS_STATUS_SUCCESS, -NSS_STATUS_NOTFOUND, -NSS_STATUS_UNAVAIL -}; + +typedef enum nss_status NSS_STATUS; + +#else /* Nothing's defined. Neither gnu nor sun */ + +typedef enum +{ + NSS_STATUS_SUCCESS, + NSS_STATUS_NOTFOUND, + NSS_STATUS_UNAVAIL, + NSS_STATUS_TRYAGAIN +} NSS_STATUS; + #endif +/* Declarations for functions in winbind_nss.c + needed in winbind_nss_solaris.c (solaris wrapper to nss) */ + +NSS_STATUS _nss_winbind_setpwent(void); +NSS_STATUS _nss_winbind_endpwent(void); +NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer, + size_t buflen, int* errnop); +NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer, + size_t buflen, int* errnop); +NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result, + char* buffer, size_t buflen, int* errnop); + +NSS_STATUS _nss_winbind_setgrent(void); +NSS_STATUS _nss_winbind_endgrent(void); +NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer, + size_t buflen, int* errnop); +NSS_STATUS _nss_winbind_getgrnam_r(const char *name, + struct group *result, char *buffer, + size_t buflen, int *errnop); +NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, + struct group *result, char *buffer, + size_t buflen, int *errnop); + /* I'm trying really hard not to include anything from smb.h with the result of some silly looking redeclaration of structures. */ @@ -127,6 +172,7 @@ typedef int BOOL; /* zero a structure given a pointer to the structure */ #define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } + /* Some systems (SCO) treat UNIX domain sockets as FIFOs */ #ifndef S_IFSOCK diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c index b0e35f3cd6e..acb251950ad 100644 --- a/source/nsswitch/winbindd.c +++ b/source/nsswitch/winbindd.c @@ -267,7 +267,8 @@ static void new_connection(int accept_sock) { struct sockaddr_un sunaddr; struct winbindd_cli_state *state; - int len, sock; + socklen_t len + int sock; /* Accept connection */ diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c index 7b263dfe009..bc519430f3a 100644 --- a/source/nsswitch/winbindd_cache.c +++ b/source/nsswitch/winbindd_cache.c @@ -39,7 +39,7 @@ void winbindd_cache_init(void) { /* Open tdb cache */ unlink(lock_path("winbindd_cache.tdb")); - if (!(cache_tdb = tdb_open(lock_path("winbindd_cache.tdb"), 0, + if (!(cache_tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 0, TDB_NOLOCK, O_RDWR | O_CREAT, 0600))) { DEBUG(0, ("Unable to open tdb cache - user and group caching " diff --git a/source/nsswitch/winbindd_idmap.c b/source/nsswitch/winbindd_idmap.c index 11f7b8aae7a..891b79c2758 100644 --- a/source/nsswitch/winbindd_idmap.c +++ b/source/nsswitch/winbindd_idmap.c @@ -210,7 +210,7 @@ BOOL winbindd_idmap_init(void) { /* Open tdb cache */ - if (!(idmap_tdb = tdb_open(lock_path("winbindd_idmap.tdb"), 0, + if (!(idmap_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0, TDB_NOLOCK | TDB_NOMMAP, O_RDWR | O_CREAT, 0600))) { DEBUG(0, ("Unable to open idmap database\n")); diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c index be76c2e54ee..dea6418cb84 100644 --- a/source/nsswitch/wins.c +++ b/source/nsswitch/wins.c @@ -31,6 +31,39 @@ extern int DEBUGLEVEL; #define INADDRSZ 4 #endif +/* Use our own create socket code so we don't recurse.... */ + +static int wins_lookup_open_socket_in(void) +{ + struct sockaddr_in sock; + int val=1; + int res; + + memset((char *)&sock,'\0',sizeof(sock)); + +#ifdef HAVE_SOCK_SIN_LEN + sock.sin_len = sizeof(sock); +#endif + sock.sin_port = 0; + sock.sin_family = AF_INET; + sock.sin_addr.s_addr = interpret_addr("0.0.0.0"); + res = socket(AF_INET, SOCK_DGRAM, 0); + if (res == -1) + return -1; + + setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)); +#ifdef SO_REUSEPORT + setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)); +#endif /* SO_REUSEPORT */ + + /* now we've got a socket - we need to bind it */ + + if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) + return(-1); + + return res; +} + struct in_addr *lookup_backend(const char *name, int *count) { int fd; @@ -51,8 +84,9 @@ struct in_addr *lookup_backend(const char *name, int *count) *count = 0; - fd = open_socket_in(SOCK_DGRAM,0, 3, interpret_addr("0.0.0.0"), True); - if (fd == -1) return NULL; + fd = wins_lookup_open_socket_in(); + if (fd == -1) + return NULL; set_socket_options(fd,"SO_BROADCAST"); @@ -85,6 +119,7 @@ struct in_addr *lookup_backend(const char *name, int *count) } out: + close(fd); return ret; } @@ -94,21 +129,24 @@ struct in_addr *lookup_backend(const char *name, int *count) gethostbyname() - we ignore any domain portion of the name and only handle names that are at most 15 characters long **************************************************************************/ -enum nss_status -_nss_wins_gethostbyname_r(const char *name, struct hostent *he, + +NSS_STATUS _nss_wins_gethostbyname_r(const char *name, struct hostent *he, char *buffer, size_t buflen, int *errnop, int *h_errnop) { char **host_addresses; struct in_addr *ip_list; int i, count; + size_t namelen = strlen(name) + 1; + + memset(he, '\0', sizeof(*he)); ip_list = lookup_backend(name, &count); if (!ip_list) { return NSS_STATUS_NOTFOUND; } - if (buflen < (2*count+1)*INADDRSZ) { + if (buflen < namelen + (2*count+1)*INADDRSZ) { /* no ENOMEM error type?! */ return NSS_STATUS_NOTFOUND; } @@ -130,7 +168,11 @@ _nss_wins_gethostbyname_r(const char *name, struct hostent *he, host_addresses++; } - if (ip_list) free(ip_list); + if (ip_list) + free(ip_list); + + memcpy(buffer, name, namelen); + he->h_name = buffer; return NSS_STATUS_SUCCESS; } diff --git a/source/param/loadparm.c b/source/param/loadparm.c index f8e540466b5..fb96c3214de 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -86,10 +86,8 @@ pstring global_scope = ""; #endif /* some helpful bits */ -#define pSERVICE(i) ServicePtrs[i] -#define iSERVICE(i) (*pSERVICE(i)) -#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid) -#define VALID(i) iSERVICE(i).valid +#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid) +#define VALID(i) ServicePtrs[i]->valid int keepalive = DEFAULT_KEEPALIVE; BOOL use_getwd_cache = True; @@ -131,8 +129,6 @@ typedef struct char *szWorkGroup; char *szDomainAdminGroup; char *szDomainGuestGroup; - char *szDomainAdminUsers; - char *szDomainGuestUsers; char *szDomainHostsallow; char *szDomainHostsdeny; char *szUsernameMap; @@ -155,7 +151,6 @@ typedef struct char *szAnnounceVersion; /* This is initialised in init_globals */ char *szNetbiosAliases; char *szDomainOtherSIDs; - char *szDomainGroups; char *szNameResolveOrder; char *szLdapServer; char *szLdapSuffix; @@ -169,9 +164,8 @@ typedef struct #ifdef WITH_UTMP char *szUtmpDir; char *szWtmpDir; - char *szUtmpHostname; - BOOL bUtmpConsolidate; -#endif /* WITH_UTMP */ + BOOL bUtmp; +#endif char *szSourceEnv; char *szWinbindUID; char *szWinbindGID; @@ -199,6 +193,7 @@ typedef struct int iTotalPrintJobs; int syslog; int os_level; + int enhanced_browsing; int max_ttl; int max_wins_ttl; int min_wins_ttl; @@ -245,18 +240,20 @@ typedef struct BOOL bUpdateEncrypt; BOOL bStripDot; BOOL bNullPasswords; + BOOL bObeyPamRestrictions; BOOL bLoadPrinters; BOOL bUseRhosts; + BOOL bLargeReadwrite; BOOL bReadRaw; BOOL bWriteRaw; BOOL bReadPrediction; BOOL bReadbmpx; BOOL bSyslogOnly; BOOL bBrowseList; - BOOL bUnixRealname; BOOL bNISHomeMap; BOOL bTimeServer; BOOL bBindInterfacesOnly; + BOOL bPamPasswordChange; BOOL bUnixPasswdSync; BOOL bPasswdChatDebug; BOOL bTimestampLogs; @@ -354,6 +351,7 @@ typedef struct BOOL bCaseMangle; BOOL status; BOOL bHideDotFiles; + BOOL bHideUnReadable; BOOL bBrowseable; BOOL bAvailable; BOOL bRead_only; @@ -368,9 +366,6 @@ typedef struct BOOL bLocking; BOOL bStrictLocking; BOOL bPosixLocking; -#ifdef WITH_UTMP - BOOL bUtmp; -#endif BOOL bShareModes; BOOL bOpLocks; BOOL bLevel2OpLocks; @@ -450,12 +445,12 @@ static service sDefault = { 0, /* iWriteCacheSize */ 0744, /* iCreate_mask */ 0000, /* iCreate_force_mode */ - -1, /* iSecurity_mask */ - -1, /* iSecurity_force_mode */ + 0777, /* iSecurity_mask */ + 0, /* iSecurity_force_mode */ 0755, /* iDir_mask */ 0000, /* iDir_force_mode */ - -1, /* iDir_Security_mask */ - -1, /* iDir_Security_force_mode */ + 0777, /* iDir_Security_mask */ + 0, /* iDir_Security_force_mode */ 0, /* iMaxConnections */ CASE_LOWER, /* iDefaultCase */ DEFAULT_PRINTING, /* iPrinting */ @@ -469,6 +464,7 @@ static service sDefault = { False, /* case mangle */ True, /* status */ True, /* bHideDotFiles */ + False, /* bHideUnReadable */ True, /* bBrowseable */ True, /* bAvailable */ True, /* bRead_only */ @@ -483,9 +479,6 @@ static service sDefault = { True, /* bLocking */ False, /* bStrictLocking */ True, /* bPosixLocking */ -#ifdef WITH_UTMP - False, /* bUtmp */ -#endif True, /* bShareModes */ True, /* bOpLocks */ True, /* bLevel2OpLocks */ @@ -678,6 +671,7 @@ static struct parm_struct parm_table[] = { {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0}, {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0}, {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0}, + {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, 0}, {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0}, /* #ifdef WITH_TDBPWD {"tdb passwd file", P_STRING, P_GLOBAL, &Globals.szTDBPasswdFile, NULL, NULL, 0}, @@ -688,6 +682,7 @@ static struct parm_struct parm_table[] = { {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0}, + {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, 0}, {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0}, {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0}, {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0}, @@ -709,7 +704,7 @@ static struct parm_struct parm_table[] = { {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, - {"printer admin", P_STRING, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE}, + {"printer admin", P_STRING, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT}, {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE}, {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE}, {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0}, @@ -780,6 +775,7 @@ static struct parm_struct parm_table[] = { {"Protocol Options", P_SEP, P_SEPARATOR}, {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0}, + {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, 0}, {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0}, {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, 0}, {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0}, @@ -867,6 +863,7 @@ static struct parm_struct parm_table[] = { {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, + {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING}, {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING}, @@ -880,11 +877,8 @@ static struct parm_struct parm_table[] = { {"Domain Options", P_SEP, P_SEPARATOR}, - {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0}, {"domain admin group", P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0}, {"domain guest group", P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0}, - {"domain admin users", P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0}, - {"domain guest users", P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0}, #ifdef USING_GROUPNAME_MAP {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0}, @@ -914,6 +908,7 @@ static struct parm_struct parm_table[] = { {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0}, {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0}, + {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL}, {"WINS Options", P_SEP, P_SEPARATOR}, {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0}, @@ -929,9 +924,6 @@ static struct parm_struct parm_table[] = { {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE}, {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL}, {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, -#ifdef WITH_UTMP - {"utmp", P_BOOL, P_LOCAL, &sDefault.bUtmp, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, -#endif {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL}, @@ -963,17 +955,13 @@ static struct parm_struct parm_table[] = { {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, #ifdef WITH_UTMP - {"utmp dir", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0}, {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0}, - {"wtmp dir", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0}, {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0}, - {"utmp hostname", P_STRING, P_GLOBAL, &Globals.szUtmpHostname, NULL, NULL, 0}, - {"utmp consolidate", P_BOOL, P_GLOBAL, &Globals.bUtmpConsolidate, NULL, NULL, 0}, -#endif /* WITH_UTMP */ + {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, 0}, +#endif - {"default service", P_STRING, P_GLOBAL, - &Globals.szDefaultService, NULL, NULL, 0}, - {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0}, + {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DOS_STRING}, + {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DOS_STRING}, {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0}, {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0}, {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0}, @@ -982,7 +970,6 @@ static struct parm_struct parm_table[] = { {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0}, {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0}, {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0}, - {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0}, {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0}, {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, @@ -997,7 +984,7 @@ static struct parm_struct parm_table[] = { {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE}, {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT}, {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, - {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE}, + {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE | FLAG_DOS_STRING}, {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE}, {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE}, {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, 0}, @@ -1018,12 +1005,12 @@ static struct parm_struct parm_table[] = { {"VFS options", P_SEP, P_SEPARATOR}, - {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, 0}, - {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, 0}, + {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, FLAG_SHARE}, + {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE}, {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE}, - {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_GLOBAL}, + {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, 0}, {"Winbind options", P_SEP, P_SEPARATOR}, @@ -1205,9 +1192,8 @@ static void init_globals(void) #ifdef WITH_UTMP string_set(&Globals.szUtmpDir, ""); string_set(&Globals.szWtmpDir, ""); - string_set(&Globals.szUtmpHostname, "%m"); - Globals.bUtmpConsolidate = False; -#endif /* WITH_UTMP */ + Globals.bUtmp = False; +#endif string_set(&Globals.szSocketAddress, "0.0.0.0"); pstrcpy(s, "Samba "); pstrcat(s, VERSION); @@ -1238,6 +1224,7 @@ static void init_globals(void) Globals.pwordlevel = 0; Globals.unamelevel = 0; Globals.deadtime = 0; + Globals.bLargeReadwrite = False; Globals.max_log_size = 5000; Globals.max_open_files = MAX_OPEN_FILES; Globals.maxprotocol = PROTOCOL_NT1; @@ -1250,6 +1237,7 @@ static void init_globals(void) Globals.bReadPrediction = False; Globals.bReadbmpx = False; Globals.bNullPasswords = False; + Globals.bObeyPamRestrictions = False; Globals.bStripDot = False; Globals.syslog = 1; Globals.bSyslogOnly = False; @@ -1267,7 +1255,6 @@ static void init_globals(void) Globals.lm_interval = 60; Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */ Globals.announce_as = ANNOUNCE_AS_NT_SERVER; - Globals.bUnixRealname = True; #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) Globals.bNISHomeMap = False; #ifdef WITH_NISPLUS_HOME @@ -1280,6 +1267,7 @@ static void init_globals(void) Globals.bTimeServer = False; Globals.bBindInterfacesOnly = False; Globals.bUnixPasswdSync = False; + Globals.bPamPasswordChange = False; Globals.bPasswdChatDebug = False; Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */ Globals.bNTPipeSupport = True; /* Do NT pipes by default. */ @@ -1290,6 +1278,7 @@ static void init_globals(void) Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ + Globals.enhanced_browsing = True; #ifdef WITH_LDAP /* default values for ldap */ @@ -1414,13 +1403,13 @@ static char *lp_string(const char *s) int fn_name(void) {return(*(int *)(ptr));} #define FN_LOCAL_STRING(fn_name,val) \ - char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));} + char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));} #define FN_LOCAL_BOOL(fn_name,val) \ - BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} + BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} #define FN_LOCAL_CHAR(fn_name,val) \ - char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} + char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} #define FN_LOCAL_INTEGER(fn_name,val) \ - int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} + int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile) FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile) @@ -1439,9 +1428,8 @@ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir) #ifdef WITH_UTMP FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir) FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir) -FN_GLOBAL_STRING(lp_utmp_hostname, &Globals.szUtmpHostname) -FN_GLOBAL_BOOL(lp_utmp_consolidate, &Globals.bUtmpConsolidate) -#endif /* WITH_UTMP */ +FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp) +#endif FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir) FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv) FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService) @@ -1474,11 +1462,8 @@ FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction) FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript) FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript) FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook) -FN_GLOBAL_STRING(lp_domain_groups, &Globals.szDomainGroups) FN_GLOBAL_STRING(lp_domain_admin_group, &Globals.szDomainAdminGroup) FN_GLOBAL_STRING(lp_domain_guest_group, &Globals.szDomainGuestGroup) -FN_GLOBAL_STRING(lp_domain_admin_users, &Globals.szDomainAdminUsers) -FN_GLOBAL_STRING(lp_domain_guest_users, &Globals.szDomainGuestUsers) FN_GLOBAL_STRING(lp_winbind_uid, &Globals.szWinbindUID) FN_GLOBAL_STRING(lp_winbind_gid, &Globals.szWinbindGID) FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir) @@ -1525,8 +1510,10 @@ FN_GLOBAL_BOOL(lp_use_rhosts, &Globals.bUseRhosts) FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction) FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx) FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw) +FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite) FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw) FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords) +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) @@ -1536,10 +1523,10 @@ FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp) FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid) FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid) FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList) -FN_GLOBAL_BOOL(lp_unix_realname, &Globals.bUnixRealname) FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap) static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer) FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly) +FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange) FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync) FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug) FN_GLOBAL_BOOL(lp_nt_smb_support, &Globals.bNTSmbSupport) @@ -1551,6 +1538,7 @@ FN_GLOBAL_BOOL(lp_restrict_anonymous, &Globals.bRestrictAnonymous) FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth) FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs) FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks) +FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing) FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level) FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl) FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl) @@ -1634,6 +1622,7 @@ FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve) FN_LOCAL_BOOL(lp_casemangle, bCaseMangle) FN_LOCAL_BOOL(lp_status, status) FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles) +FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable) FN_LOCAL_BOOL(lp_browseable, bBrowseable) FN_LOCAL_BOOL(lp_readonly, bRead_only) FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir) @@ -1646,9 +1635,6 @@ FN_LOCAL_BOOL(lp_map_archive, bMap_archive) FN_LOCAL_BOOL(lp_locking, bLocking) FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking) FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking) -#ifdef WITH_UTMP -FN_LOCAL_BOOL(lp_utmp, bUtmp) -#endif FN_LOCAL_BOOL(lp_share_modes, bShareModes) FN_LOCAL_BOOL(lp_oplocks, bOpLocks) FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks) @@ -1670,12 +1656,12 @@ FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks) FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms) FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask) FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode) -FN_LOCAL_INTEGER(_lp_security_mask, iSecurity_mask) -FN_LOCAL_INTEGER(_lp_force_security_mode, iSecurity_force_mode) +FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask) +FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode) FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask) FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode) -FN_LOCAL_INTEGER(_lp_dir_security_mask, iDir_Security_mask) -FN_LOCAL_INTEGER(_lp_force_dir_security_mode, iDir_Security_force_mode) +FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask) +FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode) FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections) FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase) FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace) @@ -1739,6 +1725,8 @@ static void free_service(service * pservice) string_free((char **) (((char *)pservice) + PTR_DIFF(parm_table[i].ptr, &sDefault))); + + ZERO_STRUCTP(pservice); } /*************************************************************************** @@ -1763,35 +1751,49 @@ static int add_a_service(service * pservice, char *name) /* find an invalid one */ for (i = 0; i < iNumServices; i++) - if (!pSERVICE(i)->valid) + if (!ServicePtrs[i]->valid) break; /* if not, then create one */ if (i == iNumServices) { +#ifdef __INSURE__ + service **oldservices = iNumServices ? malloc(sizeof(service *) * iNumServices) : NULL; + + if (iNumServices) + memcpy(oldservices, ServicePtrs, sizeof(service *) * iNumServices); +#endif + ServicePtrs = (service **) Realloc(ServicePtrs, sizeof(service *) * num_to_alloc); +#ifdef __INSURE__ + if (iNumServices && (memcmp(oldservices, ServicePtrs, sizeof(service *) * iNumServices) != 0)) { + smb_panic("add_a_service: Realloc corrupted ptrs...\n"); + } + safe_free(oldservices); +#endif + if (ServicePtrs) - pSERVICE(iNumServices) = + ServicePtrs[iNumServices] = (service *) malloc(sizeof(service)); - if (!ServicePtrs || !pSERVICE(iNumServices)) + if (!ServicePtrs || !ServicePtrs[iNumServices]) return (-1); iNumServices++; } else - free_service(pSERVICE(i)); + free_service(ServicePtrs[i]); - pSERVICE(i)->valid = True; + ServicePtrs[i]->valid = True; - init_service(pSERVICE(i)); - copy_service(pSERVICE(i), &tservice, NULL); + init_service(ServicePtrs[i]); + copy_service(ServicePtrs[i], &tservice, NULL); if (name) { - string_set(&iSERVICE(i).szService, name); + string_set(&ServicePtrs[i]->szService, name); } return (i); } @@ -1802,23 +1804,23 @@ from service ifrom. homename must be in DOS codepage. ***************************************************************************/ BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir) { - int i = add_a_service(pSERVICE(iDefaultService), pszHomename); + int i = add_a_service(ServicePtrs[iDefaultService], pszHomename); if (i < 0) return (False); - if (!(*(iSERVICE(i).szPath)) - || strequal(iSERVICE(i).szPath, lp_pathname(-1))) - string_set(&iSERVICE(i).szPath, pszHomedir); - if (!(*(iSERVICE(i).comment))) + if (!(*(ServicePtrs[i]->szPath)) + || strequal(ServicePtrs[i]->szPath, lp_pathname(-1))) + string_set(&ServicePtrs[i]->szPath, pszHomedir); + if (!(*(ServicePtrs[i]->comment))) { pstring comment; slprintf(comment, sizeof(comment) - 1, "Home directory of %s", pszHomename); - string_set(&iSERVICE(i).comment, comment); + string_set(&ServicePtrs[i]->comment, comment); } - iSERVICE(i).bAvailable = sDefault.bAvailable; - iSERVICE(i).bBrowseable = sDefault.bBrowseable; + ServicePtrs[i]->bAvailable = sDefault.bAvailable; + ServicePtrs[i]->bBrowseable = sDefault.bBrowseable; DEBUG(3, ("adding home directory %s at %s\n", pszHomename, pszHomedir)); @@ -1831,7 +1833,7 @@ add a new service, based on an old one. pszService must be in DOS codepage. ***************************************************************************/ int lp_add_service(char *pszService, int iDefaultService) { - return (add_a_service(pSERVICE(iDefaultService), pszService)); + return (add_a_service(ServicePtrs[iDefaultService], pszService)); } @@ -1849,18 +1851,18 @@ static BOOL lp_add_ipc(char *ipc_name, BOOL guest_ok) slprintf(comment, sizeof(comment) - 1, "IPC Service (%s)", Globals.szServerString); - string_set(&iSERVICE(i).szPath, tmpdir()); - string_set(&iSERVICE(i).szUsername, ""); - string_set(&iSERVICE(i).comment, comment); - string_set(&iSERVICE(i).fstype, "IPC"); - iSERVICE(i).status = False; - iSERVICE(i).iMaxConnections = 0; - iSERVICE(i).bAvailable = True; - iSERVICE(i).bRead_only = True; - iSERVICE(i).bGuest_only = False; - iSERVICE(i).bGuest_ok = guest_ok; - iSERVICE(i).bPrint_ok = False; - iSERVICE(i).bBrowseable = sDefault.bBrowseable; + string_set(&ServicePtrs[i]->szPath, tmpdir()); + string_set(&ServicePtrs[i]->szUsername, ""); + string_set(&ServicePtrs[i]->comment, comment); + string_set(&ServicePtrs[i]->fstype, "IPC"); + ServicePtrs[i]->status = False; + ServicePtrs[i]->iMaxConnections = 0; + ServicePtrs[i]->bAvailable = True; + ServicePtrs[i]->bRead_only = True; + ServicePtrs[i]->bGuest_only = False; + ServicePtrs[i]->bGuest_ok = guest_ok; + ServicePtrs[i]->bPrint_ok = False; + ServicePtrs[i]->bBrowseable = sDefault.bBrowseable; DEBUG(3, ("adding IPC service %s\n", ipc_name)); @@ -1875,7 +1877,7 @@ printername must be in DOS codepage. BOOL lp_add_printer(char *pszPrintername, int iDefaultService) { char *comment = "From Printcap"; - int i = add_a_service(pSERVICE(iDefaultService), pszPrintername); + int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername); if (i < 0) return (False); @@ -1886,17 +1888,17 @@ BOOL lp_add_printer(char *pszPrintername, int iDefaultService) /* entry (if/when the 'available' keyword is implemented!). */ /* the printer name is set to the service name. */ - string_set(&iSERVICE(i).szPrintername, pszPrintername); - string_set(&iSERVICE(i).comment, comment); - iSERVICE(i).bBrowseable = sDefault.bBrowseable; + string_set(&ServicePtrs[i]->szPrintername, pszPrintername); + string_set(&ServicePtrs[i]->comment, comment); + ServicePtrs[i]->bBrowseable = sDefault.bBrowseable; /* Printers cannot be read_only. */ - iSERVICE(i).bRead_only = False; + ServicePtrs[i]->bRead_only = False; /* No share modes on printer services. */ - iSERVICE(i).bShareModes = False; + ServicePtrs[i]->bShareModes = False; /* No oplocks on printer services. */ - iSERVICE(i).bOpLocks = False; + ServicePtrs[i]->bOpLocks = False; /* Printer services must be printable. */ - iSERVICE(i).bPrint_ok = True; + ServicePtrs[i]->bPrint_ok = True; DEBUG(3, ("adding printer service %s\n", pszPrintername)); @@ -1961,12 +1963,10 @@ static int getservicebyname(char *pszServiceName, service * pserviceDest) for (iService = iNumServices - 1; iService >= 0; iService--) if (VALID(iService) && - strwicmp(iSERVICE(iService).szService, - pszServiceName) == 0) + strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) { if (pserviceDest != NULL) - copy_service(pserviceDest, pSERVICE(iService), - NULL); + copy_service(pserviceDest, ServicePtrs[iService], NULL); break; } @@ -2049,7 +2049,7 @@ static BOOL service_ok(int iService) BOOL bRetval; bRetval = True; - if (iSERVICE(iService).szService[0] == '\0') + if (ServicePtrs[iService]->szService[0] == '\0') { DEBUG(0, ("The following message indicates an internal error:\n")); @@ -2059,31 +2059,31 @@ static BOOL service_ok(int iService) /* The [printers] entry MUST be printable. I'm all for flexibility, but */ /* I can't see why you'd want a non-printable printer service... */ - if (strwicmp(iSERVICE(iService).szService, PRINTERS_NAME) == 0) { - if (!iSERVICE(iService).bPrint_ok) { + if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) { + if (!ServicePtrs[iService]->bPrint_ok) { DEBUG(0, ("WARNING: [%s] service MUST be printable!\n", - iSERVICE(iService).szService)); - iSERVICE(iService).bPrint_ok = True; + ServicePtrs[iService]->szService)); + ServicePtrs[iService]->bPrint_ok = True; } /* [printers] service must also be non-browsable. */ - if (iSERVICE(iService).bBrowseable) - iSERVICE(iService).bBrowseable = False; + if (ServicePtrs[iService]->bBrowseable) + ServicePtrs[iService]->bBrowseable = False; } - if (iSERVICE(iService).szPath[0] == '\0' && - strwicmp(iSERVICE(iService).szService, HOMES_NAME) != 0) + if (ServicePtrs[iService]->szPath[0] == '\0' && + strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) { DEBUG(0, ("No path in service %s - using %s\n", - iSERVICE(iService).szService, tmpdir())); - string_set(&iSERVICE(iService).szPath, tmpdir()); + ServicePtrs[iService]->szService, tmpdir())); + string_set(&ServicePtrs[iService]->szPath, tmpdir()); } /* If a service is flagged unavailable, log the fact at level 0. */ - if (!iSERVICE(iService).bAvailable) + if (!ServicePtrs[iService]->bAvailable) DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n", - iSERVICE(iService).szService)); + ServicePtrs[iService]->szService)); return (bRetval); } @@ -2429,9 +2429,9 @@ static BOOL handle_copy(char *pszParmValue, char **ptr) } else { - copy_service(pSERVICE(iServiceIndex), + copy_service(ServicePtrs[iServiceIndex], &serviceTemp, - iSERVICE(iServiceIndex).copymap); + ServicePtrs[iServiceIndex]->copymap); bRetval = True; } } @@ -2528,7 +2528,7 @@ static void init_copymap(service * pservice) ***************************************************************************/ void *lp_local_ptr(int snum, void *ptr) { - return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr, &sDefault)); + return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault)); } /*************************************************************************** @@ -2573,20 +2573,20 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue) return (True); } parm_ptr = - ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr, + ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr, &sDefault); } if (snum >= 0) { - if (!iSERVICE(snum).copymap) - init_copymap(pSERVICE(snum)); + if (!ServicePtrs[snum]->copymap) + init_copymap(ServicePtrs[snum]); /* this handles the aliases - set the copymap for other entries with the same data pointer */ for (i = 0; parm_table[i].label; i++) if (parm_table[i].ptr == parm_table[parmnum].ptr) - iSERVICE(snum).copymap[i] = False; + ServicePtrs[snum]->copymap[i] = False; } /* if it is a special case then go ahead */ @@ -2921,7 +2921,7 @@ BOOL lp_is_default(int snum, struct parm_struct *parm) int pdiff = PTR_DIFF(parm->ptr, &sDefault); return equal_parameter(parm->type, - ((char *)pSERVICE(snum)) + pdiff, + ((char *)ServicePtrs[snum]) + pdiff, ((char *)&sDefault) + pdiff); } @@ -2995,7 +2995,7 @@ struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters) } else { - service *pService = pSERVICE(snum); + service *pService = ServicePtrs[snum]; for (; parm_table[*i].label; (*i)++) { @@ -3057,7 +3057,7 @@ Return TRUE if the passed service number is within range. ***************************************************************************/ BOOL lp_snum_ok(int iService) { - return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable); + return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable); } @@ -3107,9 +3107,9 @@ void lp_add_one_printer(char *name, char *comment) lp_add_printer(name, printers); if ((i = lp_servicenumber(name)) >= 0) { - string_set(&iSERVICE(i).comment, comment); - unix_to_dos(iSERVICE(i).comment, True); - iSERVICE(i).autoloaded = True; + string_set(&ServicePtrs[i]->comment, comment); + unix_to_dos(ServicePtrs[i]->comment, True); + ServicePtrs[i]->autoloaded = True; } } } @@ -3135,8 +3135,8 @@ void lp_killunused(BOOL (*snumused) (int)) if (!snumused || !snumused(i)) { - iSERVICE(i).valid = False; - free_service(pSERVICE(i)); + ServicePtrs[i]->valid = False; + free_service(ServicePtrs[i]); } } } @@ -3149,8 +3149,8 @@ void lp_killservice(int iServiceIn) { if (VALID(iServiceIn)) { - iSERVICE(iServiceIn).valid = False; - free_service(pSERVICE(iServiceIn)); + ServicePtrs[iServiceIn]->valid = False; + free_service(ServicePtrs[iServiceIn]); } } @@ -3354,9 +3354,9 @@ void lp_dump_one(FILE * f, BOOL show_defaults, int snum, char *(*dos_to_ext)(cha { if (VALID(snum)) { - if (iSERVICE(snum).szService[0] == '\0') + if (ServicePtrs[snum]->szService[0] == '\0') return; - dump_a_service(pSERVICE(snum), f, dos_to_ext); + dump_a_service(ServicePtrs[snum], f, dos_to_ext); } } @@ -3385,17 +3385,14 @@ int lp_servicenumber(char *pszServiceName) } /******************************************************************* - a useful volume label function - ******************************************************************/ + A useful volume label function. Returns a string in DOS codepage. +********************************************************************/ + char *volume_label(int snum) { char *ret = lp_volume(snum); - if (!*ret) { - /* lp_volume returns a unix charset - lp_servicename returns a - dos codepage - convert so volume_label() always returns UNIX. - */ - return (dos_to_unix(lp_servicename(snum), False)); - } + if (!*ret) + return lp_servicename(snum); return (ret); } @@ -3518,7 +3515,7 @@ remove a service ********************************************************************/ void lp_remove_service(int snum) { - pSERVICE(snum)->valid = False; + ServicePtrs[snum]->valid = False; } /******************************************************************* @@ -3601,43 +3598,6 @@ void lp_set_name_resolve_order(char *new_order) Globals.szNameResolveOrder = new_order; } -/*********************************************************** - Functions to return the current security masks/modes. If - set to -1 then return the create mask/mode instead. -************************************************************/ - -int lp_security_mask(int snum) -{ - int val = _lp_security_mask(snum); - if (val == -1) - return lp_create_mask(snum); - return val; -} - -int lp_force_security_mode(int snum) -{ - int val = _lp_force_security_mode(snum); - if (val == -1) - return lp_force_create_mode(snum); - return val; -} - -int lp_dir_security_mask(int snum) -{ - int val = _lp_dir_security_mask(snum); - if (val == -1) - return lp_dir_mask(snum); - return val; -} - -int lp_force_dir_security_mode(int snum) -{ - int val = _lp_force_dir_security_mode(snum); - if (val == -1) - return lp_force_dir_mode(snum); - return val; -} - char *lp_printername(int snum) { char *ret = _lp_printername(snum); diff --git a/source/passdb/nispass.c b/source/passdb/nispass.c index 007ae10d06d..c1a867bc338 100644 --- a/source/passdb/nispass.c +++ b/source/passdb/nispass.c @@ -49,7 +49,7 @@ extern int DEBUGLEVEL; extern pstring samlogon_user; extern BOOL sam_logon_in_ssb; -static VOLATILE SIG_ATOMIC_T gotalarm; +static VOLATILE sig_atomic_t gotalarm; /*************************************************************** diff --git a/source/passdb/pampass.c b/source/passdb/pampass.c index e6de54dfe69..53d2a062fdd 100644 --- a/source/passdb/pampass.c +++ b/source/passdb/pampass.c @@ -5,6 +5,7 @@ Copyright (C) Andrew Tridgell 1992-2001 Copyright (C) John H Terpsta 1999-2001 Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jeremy Allison 2001 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 @@ -43,65 +44,106 @@ extern int DEBUGLEVEL; #include <security/pam_appl.h> /* - * Static variables used to communicate between the conversation function - * and the server_login function + * Structure used to communicate between the conversation function + * and the server_login/change password functions. */ -static char *PAM_username; -static char *PAM_password; +struct smb_pam_userdata { + char *PAM_username; + char *PAM_password; + char *PAM_newpassword; +}; + +typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr); /* * Macros to help make life easy */ #define COPY_STRING(s) (s) ? strdup(s) : NULL -/* - * PAM error handler. - */ -static BOOL pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg, int dbglvl) +/******************************************************************* + PAM error handler. + *********************************************************************/ + +static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg, int dbglvl) { - if( pam_error != PAM_SUCCESS) - { - DEBUG(dbglvl, ("PAM: %s : %s\n", msg, pam_strerror(pamh, pam_error))); + if( pam_error != PAM_SUCCESS) { + DEBUG(dbglvl, ("smb_pam_error_handler: PAM: %s : %s\n", + msg, pam_strerror(pamh, pam_error))); + return False; } return True; } +/******************************************************************* + This function is a sanity check, to make sure that we NEVER report + failure as sucess. +*********************************************************************/ + +static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error, + char *msg, int dbglvl, uint32 *nt_status) +{ + if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl)) + return True; + + if (*nt_status == NT_STATUS_NOPROBLEMO) { + /* Complain LOUDLY */ + DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \ +error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE")); + *nt_status = NT_STATUS_LOGON_FAILURE; + } + return False; +} + /* * PAM conversation function * Here we assume (for now, at least) that echo on means login name, and * echo off means password. */ -static int PAM_conv(int num_msg, +static int smb_pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int replies = 0; struct pam_response *reply = NULL; + struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr; + + *resp = NULL; + + if (num_msg <= 0) + return PAM_CONV_ERR; + + /* + * Apparantly HPUX has a buggy PAM that doesn't support the + * appdata_ptr. Fail if this is the case. JRA. + */ + + if (udp == NULL) { + DEBUG(0,("smb_pam_conv: PAM on this system is broken - appdata_ptr == NULL !\n")); + return PAM_CONV_ERR; + } reply = malloc(sizeof(struct pam_response) * num_msg); if (!reply) return PAM_CONV_ERR; - for (replies = 0; replies < num_msg; replies++) - { - switch (msg[replies]->msg_style) - { + memset(reply, '\0', sizeof(struct pam_response) * num_msg); + + for (replies = 0; replies < num_msg; replies++) { + switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_ON: reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = - COPY_STRING(PAM_username); + reply[replies].resp = COPY_STRING(udp->PAM_username); /* PAM frees resp */ break; case PAM_PROMPT_ECHO_OFF: reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = - COPY_STRING(PAM_password); + reply[replies].resp = COPY_STRING(udp->PAM_password); /* PAM frees resp */ break; @@ -125,291 +167,712 @@ static int PAM_conv(int num_msg, return PAM_SUCCESS; } -static struct pam_conv PAM_conversation = { - &PAM_conv, - NULL +/* + * PAM password change conversation function + * Here we assume (for now, at least) that echo on means login name, and + * echo off means password. + */ + +static void special_char_sub(char *buf) +{ + all_string_sub(buf, "\\n", "", 0); + all_string_sub(buf, "\\r", "", 0); + all_string_sub(buf, "\\s", " ", 0); + all_string_sub(buf, "\\t", "\t", 0); +} + +static void pwd_sub(char *buf, char *username, char *oldpass, char *newpass) +{ + pstring_sub(buf, "%u", username); + all_string_sub(buf, "%o", oldpass, sizeof(fstring)); + all_string_sub(buf, "%n", newpass, sizeof(fstring)); +} + + +struct chat_struct { + struct chat_struct *next, *prev; + fstring prompt; + fstring reply; }; +/************************************************************** + Create a linked list containing chat data. +***************************************************************/ + +static struct chat_struct *make_pw_chat(char *p) +{ + fstring prompt; + fstring reply; + struct chat_struct *list = NULL; + struct chat_struct *t; + struct chat_struct *tmp; + + while (1) { + t = (struct chat_struct *)malloc(sizeof(*t)); + if (!t) { + DEBUG(0,("make_pw_chat: malloc failed!\n")); + return NULL; + } + + ZERO_STRUCTP(t); + + DLIST_ADD_END(list, t, tmp); + + if (!next_token(&p, prompt, NULL, sizeof(fstring))) + break; + + if (strequal(prompt,".")) + fstrcpy(prompt,"*"); + + special_char_sub(prompt); + fstrcpy(t->prompt, prompt); + + if (!next_token(&p, reply, NULL, sizeof(fstring))) + break; + + if (strequal(reply,".")) + fstrcpy(reply,""); + + special_char_sub(reply); + fstrcpy(t->reply, reply); + + } + return list; +} + +static void free_pw_chat(struct chat_struct *list) +{ + while (list) { + struct chat_struct *old_head = list; + DLIST_REMOVE(list, list); + free(old_head); + } +} + +static int smb_pam_passchange_conv(int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) +{ + int replies = 0; + struct pam_response *reply = NULL; + fstring current_prompt; + fstring current_reply; + struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr; + struct chat_struct *pw_chat= make_pw_chat(lp_passwd_chat()); + struct chat_struct *t; + BOOL found; + *resp = NULL; + + DEBUG(10,("smb_pam_passchange_conv: starting converstation for %d messages\n", num_msg)); + + if (num_msg <= 0) + return PAM_CONV_ERR; + + if (pw_chat == NULL) + return PAM_CONV_ERR; + + /* + * Apparantly HPUX has a buggy PAM that doesn't support the + * appdata_ptr. Fail if this is the case. JRA. + */ + + if (udp == NULL) { + DEBUG(0,("smb_pam_passchange_conv: PAM on this system is broken - appdata_ptr == NULL !\n")); + free_pw_chat(pw_chat); + return PAM_CONV_ERR; + } + + reply = malloc(sizeof(struct pam_response) * num_msg); + if (!reply) { + DEBUG(0,("smb_pam_passchange_conv: malloc for reply failed!\n")); + free_pw_chat(pw_chat); + return PAM_CONV_ERR; + } + + for (replies = 0; replies < num_msg; replies++) { + found = False; + DEBUG(10,("smb_pam_passchange_conv: Processing message %d\n", replies)); + switch (msg[replies]->msg_style) { + case PAM_PROMPT_ECHO_ON: + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: PAM said: %s\n", msg[replies]->msg)); + fstrcpy(current_prompt, msg[replies]->msg); + strlower(current_prompt); + for (t=pw_chat; t; t=t->next) { + if (ms_fnmatch(t->prompt, current_prompt) == 0) { + fstrcpy(current_reply, t->reply); + pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword); + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We sent: %s\n", current_reply)); + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = COPY_STRING(current_reply); + found = True; + break; + } + } + /* PAM frees resp */ + if (!found) { + DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg)); + free_pw_chat(pw_chat); + free(reply); + reply = NULL; + return PAM_CONV_ERR; + } + break; + + case PAM_PROMPT_ECHO_OFF: + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: PAM said: %s\n", msg[replies]->msg)); + fstrcpy(current_prompt, msg[replies]->msg); + strlower(current_prompt); + for (t=pw_chat; t; t=t->next) { + if (ms_fnmatch(t->prompt, current_prompt) == 0) { + fstrcpy(current_reply, t->reply); + DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We sent: %s\n", current_reply)); + pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword); + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = COPY_STRING(current_reply); +#ifdef DEBUG_PASSWORD + DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actualy sent: %s\n", current_reply)); +#endif + found = True; + break; + } + } + /* PAM frees resp */ + + if (!found) { + DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg)); + free_pw_chat(pw_chat); + free(reply); + reply = NULL; + return PAM_CONV_ERR; + } + break; + + case PAM_TEXT_INFO: + /* fall through */ + + case PAM_ERROR_MSG: + /* ignore it... */ + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = NULL; + break; + + default: + /* Must be an error of some sort... */ + free_pw_chat(pw_chat); + free(reply); + reply = NULL; + return PAM_CONV_ERR; + } + } + + free_pw_chat(pw_chat); + if (reply) + *resp = reply; + return PAM_SUCCESS; +} + +/*************************************************************************** + Free up a malloced pam_conv struct. +****************************************************************************/ + +static void smb_free_pam_conv(struct pam_conv *pconv) +{ + if (pconv) + safe_free(pconv->appdata_ptr); + + safe_free(pconv); +} + +/*************************************************************************** + Allocate a pam_conv struct. +****************************************************************************/ + +static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, char *user, + char *passwd, char *newpass) +{ + struct pam_conv *pconv = (struct pam_conv *)malloc(sizeof(struct pam_conv)); + struct smb_pam_userdata *udp = (struct smb_pam_userdata *)malloc(sizeof(struct smb_pam_userdata)); + + if (pconv == NULL || udp == NULL) { + safe_free(pconv); + safe_free(udp); + return NULL; + } + + udp->PAM_username = user; + udp->PAM_password = passwd; + udp->PAM_newpassword = newpass; + + pconv->conv = smb_pam_conv_fnptr; + pconv->appdata_ptr = (void *)udp; + return pconv; +} + /* * PAM Closing out cleanup handler */ -static BOOL proc_pam_end(pam_handle_t *pamh) + +static BOOL smb_pam_end(pam_handle_t *pamh, struct pam_conv *smb_pam_conv_ptr) { - int pam_error; + int pam_error; + + smb_free_pam_conv(smb_pam_conv_ptr); - if( pamh != NULL ) - { + if( pamh != NULL ) { pam_error = pam_end(pamh, 0); - if(pam_error_handler(pamh, pam_error, "End Cleanup Failed", 2) == True) { - DEBUG(4, ("PAM: PAM_END OK.\n")); - return True; + if(smb_pam_error_handler(pamh, pam_error, "End Cleanup Failed", 2) == True) { + DEBUG(4, ("smb_pam_end: PAM: PAM_END OK.\n")); + return True; } - } - DEBUG(2,("PAM: not initialised")); - return False; + } + DEBUG(2,("smb_pam_end: PAM: not initialised")); + return False; } /* * Start PAM authentication for specified account */ -static BOOL proc_pam_start(pam_handle_t **pamh, char *user) + +static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct pam_conv *pconv) { - int pam_error; - char * rhost; + int pam_error; - DEBUG(4,("PAM: Init user: %s\n", user)); + *pamh = (pam_handle_t *)NULL; - pam_error = pam_start("samba", user, &PAM_conversation, pamh); - if( !pam_error_handler(*pamh, pam_error, "Init Failed", 0)) { - proc_pam_end(*pamh); - return False; - } + DEBUG(4,("smb_pam_start: PAM: Init user: %s\n", user)); - rhost = client_name(); - if (strcmp(rhost,"UNKNOWN") == 0) - rhost = client_addr(); + pam_error = pam_start("samba", user, pconv, pamh); + if( !smb_pam_error_handler(*pamh, pam_error, "Init Failed", 0)) { + *pamh = (pam_handle_t *)NULL; + return False; + } + + if (rhost == NULL) { + rhost = client_name(); + if (strequal(rhost,"UNKNOWN")) + rhost = client_addr(); + } #ifdef PAM_RHOST - DEBUG(4,("PAM: setting rhost to: %s\n", rhost)); - pam_error = pam_set_item(*pamh, PAM_RHOST, rhost); - if(!pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) { - proc_pam_end(*pamh); - return False; - } + DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", rhost)); + pam_error = pam_set_item(*pamh, PAM_RHOST, rhost); + if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) { + smb_pam_end(*pamh, pconv); + *pamh = (pam_handle_t *)NULL; + return False; + } #endif #ifdef PAM_TTY - DEBUG(4,("PAM: setting tty\n")); - pam_error = pam_set_item(*pamh, PAM_TTY, "samba"); - if (!pam_error_handler(*pamh, pam_error, "set tty failed", 0)) { - proc_pam_end(*pamh); - return False; - } + DEBUG(4,("smb_pam_start: PAM: setting tty\n")); + pam_error = pam_set_item(*pamh, PAM_TTY, "samba"); + if (!smb_pam_error_handler(*pamh, pam_error, "set tty failed", 0)) { + smb_pam_end(*pamh, pconv); + *pamh = (pam_handle_t *)NULL; + return False; + } #endif - DEBUG(4,("PAM: Init passed for user: %s\n", user)); - return True; + DEBUG(4,("smb_pam_start: PAM: Init passed for user: %s\n", user)); + return True; } /* * PAM Authentication Handler */ -static BOOL pam_auth(pam_handle_t *pamh, char *user, char *password) +static uint32 smb_pam_auth(pam_handle_t *pamh, char *user) { int pam_error; + uint32 nt_status = NT_STATUS_LOGON_FAILURE; /* * To enable debugging set in /etc/pam.d/samba: * auth required /lib/security/pam_pwdb.so nullok shadow audit */ - DEBUG(4,("PAM: Authenticate User: %s\n", user)); - pam_error = pam_authenticate(pamh, PAM_SILENT); /* Can we authenticate user? */ + DEBUG(4,("smb_pam_auth: PAM: Authenticate User: %s\n", user)); + pam_error = pam_authenticate(pamh, PAM_SILENT | lp_null_passwords() ? 0 : PAM_DISALLOW_NULL_AUTHTOK); switch( pam_error ){ case PAM_AUTH_ERR: - DEBUG(2, ("PAM: Athentication Error\n")); + DEBUG(2, ("smb_pam_auth: PAM: Athentication Error for user %s\n", user)); + nt_status = NT_STATUS_WRONG_PASSWORD; break; case PAM_CRED_INSUFFICIENT: - DEBUG(2, ("PAM: Insufficient Credentials\n")); + DEBUG(2, ("smb_pam_auth: PAM: Insufficient Credentials for user %s\n", user)); + nt_status = NT_STATUS_INSUFFICIENT_LOGON_INFO; break; case PAM_AUTHINFO_UNAVAIL: - DEBUG(2, ("PAM: Authentication Information Unavailable\n")); + DEBUG(2, ("smb_pam_auth: PAM: Authentication Information Unavailable for user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; break; case PAM_USER_UNKNOWN: - DEBUG(2, ("PAM: Username NOT known to Authentication system\n")); + DEBUG(2, ("smb_pam_auth: PAM: Username %s NOT known to Authentication system\n", user)); + nt_status = NT_STATUS_NO_SUCH_USER; break; case PAM_MAXTRIES: - DEBUG(2, ("PAM: One or more authentication modules reports user limit exceeeded\n")); + DEBUG(2, ("smb_pam_auth: PAM: One or more authentication modules reports user limit for user %s exceeeded\n", user)); + nt_status = NT_STATUS_REMOTE_SESSION_LIMIT; break; case PAM_ABORT: - DEBUG(0, ("PAM: One or more PAM modules failed to load\n")); + DEBUG(0, ("smb_pam_auth: PAM: One or more PAM modules failed to load for user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; + break; + case PAM_SUCCESS: + DEBUG(4, ("smb_pam_auth: PAM: User %s Authenticated OK\n", user)); + nt_status = NT_STATUS_NOPROBLEMO; break; - case PAM_SUCCESS: - DEBUG(4, ("PAM: User %s Authenticated OK\n", user)); - break; default: - DEBUG(0, ("PAM: UNKNOWN ERROR while authenticating user %s\n", user)); - } - if(!pam_error_handler(pamh, pam_error, "Authentication Failure", 2)) { - proc_pam_end(pamh); - return False; + DEBUG(0, ("smb_pam_auth: PAM: UNKNOWN ERROR while authenticating user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; + break; } - /* If this point is reached, the user has been authenticated. */ - return (True); + + smb_pam_nt_status_error_handler(pamh, pam_error, "Authentication Failure", 2, &nt_status); + return nt_status; } /* * PAM Account Handler */ -static BOOL pam_account(pam_handle_t *pamh, char * user, char * password) +static uint32 smb_pam_account(pam_handle_t *pamh, char * user) { int pam_error; + uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED; - DEBUG(4,("PAM: Account Management for User: %s\n", user)); + DEBUG(4,("smb_pam_account: PAM: Account Management for User: %s\n", user)); pam_error = pam_acct_mgmt(pamh, PAM_SILENT); /* Is user account enabled? */ switch( pam_error ) { case PAM_AUTHTOK_EXPIRED: - DEBUG(2, ("PAM: User is valid but password is expired\n")); + DEBUG(2, ("smb_pam_account: PAM: User %s is valid but password is expired\n", user)); + nt_status = NT_STATUS_PASSWORD_EXPIRED; break; case PAM_ACCT_EXPIRED: - DEBUG(2, ("PAM: User no longer permitted to access system\n")); + DEBUG(2, ("smb_pam_account: PAM: User %s no longer permitted to access system\n", user)); + nt_status = NT_STATUS_ACCOUNT_EXPIRED; break; case PAM_AUTH_ERR: - DEBUG(2, ("PAM: There was an authentication error\n")); + DEBUG(2, ("smb_pam_account: PAM: There was an authentication error for user %s\n", user)); + nt_status = NT_STATUS_LOGON_FAILURE; break; case PAM_PERM_DENIED: - DEBUG(0, ("PAM: User is NOT permitted to access system at this time\n")); + DEBUG(0, ("smb_pam_account: PAM: User %s is NOT permitted to access system at this time\n", user)); + nt_status = NT_STATUS_ACCOUNT_RESTRICTION; break; case PAM_USER_UNKNOWN: - DEBUG(0, ("PAM: User \"%s\" is NOT known to account management\n", user)); + DEBUG(0, ("smb_pam_account: PAM: User \"%s\" is NOT known to account management\n", user)); + nt_status = NT_STATUS_NO_SUCH_USER; + break; + case PAM_SUCCESS: + DEBUG(4, ("smb_pam_account: PAM: Account OK for User: %s\n", user)); + nt_status = NT_STATUS_NOPROBLEMO; break; - case PAM_SUCCESS: - DEBUG(4, ("PAM: Account OK for User: %s\n", user)); - break; default: - DEBUG(0, ("PAM: UNKNOWN ERROR for User: %s\n", user)); - } - if(!pam_error_handler(pamh, pam_error, "Account Check Failed", 2)) { - proc_pam_end(pamh); - return False; + nt_status = NT_STATUS_ACCOUNT_DISABLED; + DEBUG(0, ("smb_pam_account: PAM: UNKNOWN PAM ERROR (%d) during Account Management for User: %s\n", pam_error, user)); + break; } + smb_pam_nt_status_error_handler(pamh, pam_error, "Account Check Failed", 2, &nt_status); + return nt_status; +} + +/* + * PAM Credential Setting + */ + +static uint32 smb_pam_setcred(pam_handle_t *pamh, char * user) +{ + int pam_error; + uint32 nt_status = NT_STATUS_NO_TOKEN; + /* * This will allow samba to aquire a kerberos token. And, when * exporting an AFS cell, be able to /write/ to this cell. */ - DEBUG(4,("PAM: Account Management SetCredentials for User: %s\n", user)); + DEBUG(4,("PAM: Account Management SetCredentials for User: %s\n", user)); pam_error = pam_setcred(pamh, (PAM_ESTABLISH_CRED|PAM_SILENT)); - if(!pam_error_handler(pamh, pam_error, "Set Credential Failure", 2)) { - proc_pam_end(pamh); + switch( pam_error ) { + case PAM_CRED_UNAVAIL: + DEBUG(0, ("smb_pam_setcred: PAM: Credentials not found for user:%s\n", user )); + nt_status = NT_STATUS_NO_TOKEN; + break; + case PAM_CRED_EXPIRED: + DEBUG(0, ("smb_pam_setcred: PAM: Credentials for user: \"%s\" EXPIRED!\n", user )); + nt_status = NT_STATUS_PASSWORD_EXPIRED; + break; + case PAM_USER_UNKNOWN: + DEBUG(0, ("smb_pam_setcred: PAM: User: \"%s\" is NOT known so can not set credentials!\n", user )); + nt_status = NT_STATUS_NO_SUCH_USER; + break; + case PAM_CRED_ERR: + DEBUG(0, ("smb_pam_setcred: PAM: Unknown setcredentials error - unable to set credentials for %s\n", user )); + nt_status = NT_STATUS_LOGON_FAILURE; + break; + case PAM_SUCCESS: + DEBUG(4, ("smb_pam_setcred: PAM: SetCredentials OK for User: %s\n", user)); + nt_status = NT_STATUS_NOPROBLEMO; + break; + default: + DEBUG(0, ("smb_pam_setcred: PAM: UNKNOWN PAM ERROR (%d) during SetCredentials for User: %s\n", pam_error, user)); + nt_status = NT_STATUS_NO_TOKEN; + break; + } + + smb_pam_nt_status_error_handler(pamh, pam_error, "Set Credential Failure", 2, &nt_status); + return nt_status; +} + +/* + * PAM Internal Session Handler + */ +static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag) +{ + int pam_error; + +#ifdef PAM_TTY + DEBUG(4,("smb_internal_pam_session: PAM: tty set to: %s\n", tty)); + pam_error = pam_set_item(pamh, PAM_TTY, tty); + if (!smb_pam_error_handler(pamh, pam_error, "set tty failed", 0)) return False; +#endif + + if (flag) { + pam_error = pam_open_session(pamh, PAM_SILENT); + if (!smb_pam_error_handler(pamh, pam_error, "session setup failed", 0)) + return False; + } else { + pam_setcred(pamh, (PAM_DELETE_CRED|PAM_SILENT)); /* We don't care if this fails */ + pam_error = pam_close_session(pamh, PAM_SILENT); /* This will probably pick up the error anyway */ + if (!smb_pam_error_handler(pamh, pam_error, "session close failed", 0)) + return False; } - - /* If this point is reached, the user has been authenticated. */ return (True); } - /* - * PAM Internal Session Handler + * Internal PAM Password Changer. */ -static BOOL proc_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag) + +static BOOL smb_pam_chauthtok(pam_handle_t *pamh, char * user) { - int pam_error; + int pam_error; - PAM_password = NULL; - PAM_username = user; + DEBUG(4,("smb_pam_chauthtok: PAM: Password Change for User: %s\n", user)); -#ifdef PAM_TTY - DEBUG(4,("PAM: tty set to: %s\n", tty)); - pam_error = pam_set_item(pamh, PAM_TTY, tty); - if (!pam_error_handler(pamh, pam_error, "set tty failed", 0)) { - proc_pam_end(pamh); - return False; - } + pam_error = pam_chauthtok(pamh, PAM_SILENT); /* Change Password */ + + switch( pam_error ) { + case PAM_AUTHTOK_ERR: + DEBUG(2, ("PAM: unable to obtain the new authentication token - is password to weak?\n")); + break; + + /* This doesn't seem to be defined on Solaris. JRA */ +#ifdef PAM_AUTHTOK_RECOVER_ERR + case PAM_AUTHTOK_RECOVER_ERR: + DEBUG(2, ("PAM: unable to obtain the old authentication token - was the old password wrong?.\n")); + break; #endif - if (flag) { - pam_error = pam_open_session(pamh, PAM_SILENT); - if (!pam_error_handler(pamh, pam_error, "session setup failed", 0)) { - proc_pam_end(pamh); - return False; - } - } - else - { - pam_error = pam_close_session(pamh, PAM_SILENT); - if (!pam_error_handler(pamh, pam_error, "session close failed", 0)) { - proc_pam_end(pamh); - return False; - } - } - return (True); + case PAM_AUTHTOK_LOCK_BUSY: + DEBUG(2, ("PAM: unable to change the authentication token since it is currently locked.\n")); + break; + case PAM_AUTHTOK_DISABLE_AGING: + DEBUG(2, ("PAM: Authentication token aging has been disabled.\n")); + break; + case PAM_PERM_DENIED: + DEBUG(0, ("PAM: Permission denied.\n")); + break; + case PAM_TRY_AGAIN: + DEBUG(0, ("PAM: Could not update all authentication token(s). No authentication tokens were updated.\n")); + break; + case PAM_USER_UNKNOWN: + DEBUG(0, ("PAM: User not known to PAM\n")); + break; + case PAM_SUCCESS: + DEBUG(4, ("PAM: Account OK for User: %s\n", user)); + break; + default: + DEBUG(0, ("PAM: UNKNOWN PAM ERROR (%d) for User: %s\n", pam_error, user)); + } + + if(!smb_pam_error_handler(pamh, pam_error, "Password Change Failed", 2)) { + return False; + } + + /* If this point is reached, the password has changed. */ + return True; } /* * PAM Externally accessible Session handler */ -BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty) + +BOOL smb_pam_claim_session(char *user, char *tty, char *rhost) { pam_handle_t *pamh = NULL; - char * user; + struct pam_conv *pconv = NULL; + + /* Ignore PAM if told to. */ + + if (!lp_obey_pam_restrictions()) + return True; - user = malloc(strlen(conn->user)+1); - if ( user == NULL ) - { - DEBUG(0, ("PAM: PAM_session Malloc Failed!\n")); + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL) return False; - } - /* This is freed by PAM */ - StrnCpy(user, conn->user, strlen(conn->user)+1); + if (!smb_pam_start(&pamh, user, rhost, pconv)) + return False; - if (!proc_pam_start(&pamh, user)) - { - proc_pam_end(pamh); - return False; + if (!smb_internal_pam_session(pamh, user, tty, True)) { + smb_pam_end(pamh, pconv); + return False; } - if (proc_pam_session(pamh, user, tty, flag)) - { - return proc_pam_end(pamh); - } - else - { - proc_pam_end(pamh); - return False; + return smb_pam_end(pamh, pconv); +} + +/* + * PAM Externally accessible Session handler + */ + +BOOL smb_pam_close_session(char *user, char *tty, char *rhost) +{ + pam_handle_t *pamh = NULL; + struct pam_conv *pconv = NULL; + + /* Ignore PAM if told to. */ + + if (!lp_obey_pam_restrictions()) + return True; + + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL) + return False; + + if (!smb_pam_start(&pamh, user, rhost, pconv)) + return False; + + if (!smb_internal_pam_session(pamh, user, tty, False)) { + smb_pam_end(pamh, pconv); + return False; } + + return smb_pam_end(pamh, pconv); } /* * PAM Externally accessible Account handler */ -BOOL pam_accountcheck(char * user) + +uint32 smb_pam_accountcheck(char * user) { + uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED; pam_handle_t *pamh = NULL; + struct pam_conv *pconv = NULL; - PAM_username = user; - PAM_password = NULL; + /* Ignore PAM if told to. */ - if( proc_pam_start(&pamh, user)) - { - if ( pam_account(pamh, user, NULL)) - { - return( proc_pam_end(pamh)); - } - } - DEBUG(0, ("PAM: Account Validation Failed - Rejecting User!\n")); - return( False ); + if (!lp_obey_pam_restrictions()) + return NT_STATUS_NOPROBLEMO; + + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL) + return False; + + if (!smb_pam_start(&pamh, user, NULL, pconv)) + return NT_STATUS_ACCOUNT_DISABLED; + + if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO) + DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user)); + + smb_pam_end(pamh, pconv); + return nt_status; } /* * PAM Password Validation Suite */ -BOOL pam_passcheck(char * user, char * password) + +uint32 smb_pam_passcheck(char * user, char * password) { pam_handle_t *pamh = NULL; + uint32 nt_status = NT_STATUS_LOGON_FAILURE; + struct pam_conv *pconv = NULL; - PAM_username = user; - PAM_password = password; + /* + * Note we can't ignore PAM here as this is the only + * way of doing auths on plaintext passwords when + * compiled --with-pam. + */ - if( proc_pam_start(&pamh, user)) - { - if ( pam_auth(pamh, user, password)) - { - if ( pam_account(pamh, user, password)) - { - return( proc_pam_end(pamh)); - } - } + if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, password, NULL)) == NULL) + return NT_STATUS_LOGON_FAILURE; + + if (!smb_pam_start(&pamh, user, NULL, pconv)) + return NT_STATUS_LOGON_FAILURE; + + if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_NOPROBLEMO) { + DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user)); + smb_pam_end(pamh, pconv); + return nt_status; + } + + if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO) { + DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user)); + smb_pam_end(pamh, pconv); + return nt_status; + } + + if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_NOPROBLEMO) { + DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user)); + smb_pam_end(pamh, pconv); + return nt_status; + } + + smb_pam_end(pamh, pconv); + return nt_status; +} + +/* + * PAM Password Change Suite + */ + +BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword) +{ + /* Appropriate quantities of root should be obtained BEFORE calling this function */ + struct pam_conv *pconv = NULL; + pam_handle_t *pamh = NULL; + + if ((pconv = smb_setup_pam_conv(smb_pam_passchange_conv, user, oldpassword, newpassword)) == NULL) + return False; + + if(!smb_pam_start(&pamh, user, NULL, pconv)) + return False; + + if (!smb_pam_chauthtok(pamh, user)) { + DEBUG(0, ("smb_pam_passchange: PAM: Password Change Failed for user %s!\n", user)); + smb_pam_end(pamh, pconv); + return False; } - DEBUG(0, ("PAM: System Validation Failed - Rejecting User!\n")); - return( False ); + + return smb_pam_end(pamh, pconv); } #else - /* Do *NOT* make this function static. Doing so breaks the compile on gcc */ +/* If PAM not used, no PAM restrictions on accounts. */ + uint32 smb_pam_accountcheck(char * user) +{ + return NT_STATUS_NOPROBLEMO; +} - void pampass_dummy_function( void ) { } /*This stops compiler complaints */ +/* If PAM not used, also no PAM restrictions on sessions. */ + BOOL smb_pam_claim_session(char *user, char *tty, char *rhost) +{ + return True; +} +/* If PAM not used, also no PAM restrictions on sessions. */ + BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost) +{ + return True; +} #endif /* WITH_PAM */ diff --git a/source/passdb/pass_check.c b/source/passdb/pass_check.c index 236465bc903..9424189b236 100644 --- a/source/passdb/pass_check.c +++ b/source/passdb/pass_check.c @@ -599,7 +599,7 @@ static BOOL password_check(char *password) { #ifdef WITH_PAM - return (pam_passcheck(this_user, password)); + return (smb_pam_passcheck(this_user, password) == NT_STATUS_NOPROBLEMO); #endif /* WITH_PAM */ #ifdef WITH_AFS @@ -681,12 +681,13 @@ the function pointer fn() points to a function to call when a successful match is found and is used to update the encrypted password file return True on correct match, False otherwise ****************************************************************************/ + BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd, BOOL (*fn) (char *, char *)) { pstring pass2; int level = lp_passwordlevel(); - struct passwd *pass; + struct passwd *pass = NULL; if (password) password[pwlen] = 0; @@ -708,8 +709,20 @@ BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd, pass = Get_Pwnam(user, True); } +#ifdef WITH_PAM + + /* + * If we're using PAM we want to short-circuit all the + * checks below and dive straight into the PAM code. + */ + + fstrcpy(this_user, user); + + DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen)); + +#else /* Not using PAM */ - DEBUG(4, ("Checking password for user %s (l=%d)\n", user, pwlen)); + DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen)); if (!pass) { DEBUG(3, ("Couldn't find user %s\n", user)); @@ -802,6 +815,8 @@ BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd, } } +#endif /* WITH_PAM */ + /* try it as it came to us */ if (password_check(password)) { if (fn) diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c index 9fc280c2580..e1d7dca39a6 100644 --- a/source/passdb/passdb.c +++ b/source/passdb/passdb.c @@ -897,6 +897,10 @@ BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid) return False; } + + /* These parameters where removed. Use the 'domain admins' or 'domain + guests' instead. --jerry */ +#if 0 /* JERRY */ if (user_in_list(user_name, lp_domain_guest_users())) { *u_rid = DOMAIN_USER_RID_GUEST; @@ -907,10 +911,11 @@ BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid) } else { - /* turn the unix UID into a Domain RID. this is what the posix - sub-system does (adds 1000 to the uid) */ - *u_rid = pdb_uid_to_user_rid(pw->pw_uid); - } +#endif + + /* turn the unix UID into a Domain RID. this is what the posix + sub-system does (adds 1000 to the uid) */ + *u_rid = pdb_uid_to_user_rid(pw->pw_uid); /* absolutely no idea what to do about the unix GID to Domain RID mapping */ *g_rid = pdb_gid_to_group_rid(pw->pw_gid); @@ -1235,13 +1240,17 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) if(rid == DOMAIN_USER_RID_ADMIN) { pstring admin_users; char *p = admin_users; +#if 0 /* JERRY */ pstrcpy( admin_users, lp_domain_admin_users()); +#endif if(!next_token(&p, name, NULL, sizeof(fstring))) fstrcpy(name, "Administrator"); } else if (rid == DOMAIN_USER_RID_GUEST) { pstring guest_users; char *p = guest_users; +#if 0 /* JERRY */ pstrcpy( guest_users, lp_domain_guest_users()); +#endif if(!next_token(&p, name, NULL, sizeof(fstring))) fstrcpy(name, "Guest"); } else { diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c index 4d42469e3d5..be528abae73 100644 --- a/source/passdb/secrets.c +++ b/source/passdb/secrets.c @@ -41,7 +41,7 @@ BOOL secrets_init(void) *p = 0; pstrcat(fname,"/secrets.tdb"); - tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT, 0600); + tdb = tdb_open_log(fname, 0, 0, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("Failed to open %s\n", fname)); @@ -183,3 +183,32 @@ BOOL trust_password_delete(char *domain) { return secrets_delete(trust_keystr(domain)); } + +/******************************************************************* + Reset the 'done' variables so after a client process is created + from a fork call these calls will be re-done. This should be + expanded if more variables need reseting. + ******************************************************************/ + +void reset_globals_after_fork(void) +{ + unsigned char dummy; + + /* + * Increment the global seed value to ensure every smbd starts + * with a new random seed. + */ + + if (tdb) { + uint32 initial_val = sys_getpid(); + tdb_change_int_atomic(tdb, "INFO/random_seed", (int *)&initial_val, 1); + set_rand_reseed_data((unsigned char *)&initial_val, sizeof(initial_val)); + } + + /* + * Re-seed the random crypto generator, so all smbd's + * started from the same parent won't generate the same + * sequence. + */ + generate_random_buffer( &dummy, 1, True); +} diff --git a/source/passdb/smbpass.c b/source/passdb/smbpass.c index 34f083a0c2d..8635b6113ff 100644 --- a/source/passdb/smbpass.c +++ b/source/passdb/smbpass.c @@ -471,10 +471,7 @@ static struct sam_passwd* build_sampw_from_smbpw (struct smb_passwd *pw_buf) user.user_rid = pdb_uid_to_user_rid (user.smb_userid); user.group_rid = pdb_gid_to_group_rid(user.smb_grpid ); - if (lp_unix_realname()) - pstrcpy(full_name, pwfile->pw_gecos); - else - pstrcpy(full_name , "<Full Name>"); + pstrcpy(full_name, pwfile->pw_gecos); pstrcpy(logon_script , lp_logon_script ()); pstrcpy(profile_path , lp_logon_path ()); pstrcpy(home_drive , lp_logon_drive ()); @@ -1362,7 +1359,7 @@ struct sam_passwd *smbiterate_getsam21pwuid(uid_t uid) if (smbpw != NULL) { pwd = build_sampw_from_smbpw (smbpw); - DEBUG(10, ("found by user_uid: %d\n", uid)); + DEBUG(10, ("found by user_uid: %u\n", (unsigned int)uid)); } return pwd; diff --git a/source/passdb/tdbpass.c b/source/passdb/tdbpass.c index 157a7ee59e7..0d9a0f7780b 100644 --- a/source/passdb/tdbpass.c +++ b/source/passdb/tdbpass.c @@ -89,10 +89,10 @@ static struct tdb_enum_info tdb_ent; static void *startsamtdbpwent(BOOL update) { /* Open tdb passwd */ - if (!(tdb_ent.passwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, update ? O_RDWR : O_RDONLY, 0600))) + if (!(tdb_ent.passwd_tdb = tdb_open_log(lp_tdb_passwd_file(), 0, 0, update ? O_RDWR : O_RDONLY, 0600))) { DEBUG(0, ("Unable to open TDB passwd, trying create new!\n")); - if (!(tdb_ent.passwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600))) + if (!(tdb_ent.passwd_tdb = tdb_open_log(lp_tdb_passwd_file(), 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600))) { DEBUG(0, ("Unable to creat TDB passwd (smbpasswd.tdb) !!!")); return NULL; @@ -177,7 +177,7 @@ static BOOL del_samtdbpwd_entry(const char *name) TDB_DATA key; fstring keystr; - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) + if (!(pwd_tdb = tdb_open_log(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) { DEBUG(0, ("Unable to open TDB passwd!")); return False; @@ -217,7 +217,7 @@ static BOOL mod_samtdb21pwd_entry(struct sam_passwd* newpwd, BOOL override) int unknown_str_len = (newpwd->unknown_str) ? (strlen (newpwd->unknown_str) + 1) : 0; int munged_dial_len = (newpwd->munged_dial) ? (strlen (newpwd->munged_dial) + 1) : 0; - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) + if (!(pwd_tdb = tdb_open_log(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) { DEBUG(0, ("Unable to open TDB passwd!")); return False; @@ -328,7 +328,7 @@ static BOOL add_samtdb21pwd_entry(struct sam_passwd *newpwd) int unknown_str_len = (newpwd->unknown_str) ? (strlen (newpwd->unknown_str) + 1) : 1; int munged_dial_len = (newpwd->munged_dial) ? (strlen (newpwd->munged_dial) + 1) : 1; - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) + if (!(pwd_tdb = tdb_open_log(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) { DEBUG(0, ("Unable to open TDB passwd!")); return False; @@ -456,7 +456,7 @@ static struct sam_passwd *getsamtdb21pwnam(char *name) TDB_DATA key; fstring keystr; - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDONLY, 0600))) + if (!(pwd_tdb = tdb_open_log(lp_tdb_passwd_file(), 0, 0, O_RDONLY, 0600))) { DEBUG(0, ("Unable to open TDB passwd!")); return False; diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index 0aa3b96cddb..5e28f3e5b60 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -180,7 +180,7 @@ BOOL nt_printing_init(void) char *vstring = "INFO/version"; if (tdb && local_pid == sys_getpid()) return True; - tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); + tdb = tdb_open_log(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("Failed to open nt drivers database %s (%s)\n", lock_path("ntdrivers.tdb"), strerror(errno) )); @@ -644,19 +644,15 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in, DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n", driverpath, cversion)); - fsp->conn->vfs_ops.close(fsp, fsp->fd); - file_free(fsp); + close_file(fsp, True); close_cnum(conn, user->vuid); pop_sec_ctx(); return cversion; error_exit: - if(fsp) { - if(fsp->fd != -1) - fsp->conn->vfs_ops.close(fsp, fsp->fd); - file_free(fsp); - } + if(fsp) + close_file(fsp, True); close_cnum(conn, user->vuid); pop_sec_ctx(); @@ -1138,9 +1134,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time)); } } - fsp->conn->vfs_ops.close(fsp, fsp->fd); - file_free(fsp); - + close_file(fsp, True); /* Get file version info (if available) for new file */ pstrcpy(filepath, new_file); @@ -1169,8 +1163,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time)); } } - fsp->conn->vfs_ops.close(fsp, fsp->fd); - file_free(fsp); + close_file(fsp, True); if (use_version) { /* Compare versions and choose the larger version number */ @@ -1198,11 +1191,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, } error_exit: - if(fsp) { - file_free(fsp); - if(fsp->fd != -1) - fsp->conn->vfs_ops.close(fsp, fsp->fd); - } + if(fsp) + close_file(fsp, True); return -1; } @@ -2372,8 +2362,18 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME); fstrcpy(info.drivername, lp_printerdriver(snum)); +#if 0 /* JERRY */ if (!*info.drivername) fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER"); +#else + /* by setting the driver name to an empty string, a local NT admin + can now run the **local** APW to install a local printer driver + for a Samba shared printer in 2.2. Without this, drivers **must** be + installed on the Samba server for NT clients --jerry */ + if (!*info.drivername) + fstrcpy(info.drivername, ""); +#endif + DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername)); @@ -2834,6 +2834,113 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) return result; } + +/**************************************************************************** + Determine whether or not a particular driver is currently assigned + to a printer +****************************************************************************/ +BOOL printer_driver_in_use (char *arch, char *driver) +{ + TDB_DATA kbuf, newkey, dbuf; + NT_PRINTER_INFO_LEVEL_2 info; + int ret; + + if (!tdb) + nt_printing_init(); + + DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n")); + + /* loop through the printers.tdb and check for the drivername */ + for (kbuf = tdb_firstkey(tdb); kbuf.dptr; + newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) + { + + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) + continue; + + if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0) + continue; + + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff", + &info.attributes, + &info.priority, + &info.default_priority, + &info.starttime, + &info.untiltime, + &info.status, + &info.cjobs, + &info.averageppm, + &info.changeid, + &info.c_setprinter, + &info.setuptime, + info.servername, + info.printername, + info.sharename, + info.portname, + info.drivername, + info.comment, + info.location, + info.sepfile, + info.printprocessor, + info.datatype, + info.parameters); + + safe_free(dbuf.dptr); + + if (ret == -1) { + DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n", + info.printername)); + continue; + } + + DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n", + info.printername, info.drivername)); + + if (strcmp(info.drivername, driver) == 0) + { + DEBUG(5,("printer_driver_in_use: Printer %s using %s\n", + info.printername, driver)); + return True; + } + } + DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n")); + + + + /* report that the driver is in use by default */ + return False; +} + +/**************************************************************************** + Remove a printer driver from the TDB. This assumes that the the driver was + previously looked up. + ***************************************************************************/ +uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i) +{ + pstring key; + fstring arch; + TDB_DATA kbuf; + + + get_short_archi(arch, i->environment); + slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, + arch, i->cversion, i->name); + DEBUG(5,("delete_printer_driver: key = [%s]\n", key)); + + kbuf.dptr=key; + kbuf.dsize=strlen(key)+1; + + if (tdb_delete(tdb, kbuf) == -1) { + DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key)); + return NT_STATUS_ACCESS_VIOLATION; + } + + DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n", + i->name)); + + return NT_STATUS_NO_PROBLEMO; +} /**************************************************************************** ****************************************************************************/ BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index, @@ -3029,16 +3136,19 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx) if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) { sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN); } else { + uint32 owner_rid; + + /* Backup plan - make printer owned by admins or root. + This should emulate a lanman printer as security + settings can't be changed. */ - /* Backup plan - make printer owned by admins or root. This should - emulate a lanman printer as security settings can't be - changed. */ + sid_peek_rid(&owner_sid, &owner_rid); - if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) && - !lookup_name( "Administrators", &owner_sid, &name_type) && - !lookup_name( "Administrator", &owner_sid, &name_type) && - !lookup_name("root", &owner_sid, &name_type)) { - sid_copy(&owner_sid, &global_sid_World); + if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS && + owner_rid != BUILTIN_ALIAS_RID_ADMINS && + owner_rid != DOMAIN_USER_RID_ADMIN && + !lookup_name("root", &owner_sid, &name_type)) { + sid_copy(&owner_sid, &global_sid_World); } } @@ -3145,20 +3255,20 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secde } if (DEBUGLEVEL >= 10) { - SEC_ACL *acl = (*secdesc_ctr)->sec->dacl; + SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl; int i; DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", - printername, acl->num_aces)); + printername, the_acl->num_aces)); - for (i = 0; i < acl->num_aces; i++) { + for (i = 0; i < the_acl->num_aces; i++) { fstring sid_str; - sid_to_string(sid_str, &acl->ace[i].sid); + sid_to_string(sid_str, &the_acl->ace[i].sid); DEBUG(10, ("%s %d %d 0x%08x\n", sid_str, - acl->ace[i].type, acl->ace[i].flags, - acl->ace[i].info.mask)); + the_acl->ace[i].type, the_acl->ace[i].flags, + the_acl->ace[i].info.mask)); } } diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c index 6a8e4bea450..6545dc59c22 100644 --- a/source/printing/printfsp.c +++ b/source/printing/printfsp.c @@ -29,7 +29,7 @@ open a print file and setup a fsp for it. This is a wrapper around print_job_start(). ***************************************************************************/ -files_struct *print_fsp_open(connection_struct *conn,char *jobname) +files_struct *print_fsp_open(connection_struct *conn) { int jobid; SMB_STRUCT_STAT sbuf; @@ -39,7 +39,7 @@ files_struct *print_fsp_open(connection_struct *conn,char *jobname) if(!fsp) return NULL; - jobid = print_job_start(¤t_user, SNUM(conn), jobname); + jobid = print_job_start(¤t_user, SNUM(conn), "smb.prn"); if (jobid == -1) { file_free(fsp); return NULL; diff --git a/source/printing/printing.c b/source/printing/printing.c index f1c5bff275d..aab4c2f43f3 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -55,7 +55,7 @@ BOOL print_backend_init(void) char *sversion = "INFO/version"; if (tdb && local_pid == sys_getpid()) return True; - tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); + tdb = tdb_open_log(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n", tdb_errorstr(tdb))); @@ -845,6 +845,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) SMB_BIG_UINT dspace, dsize; if (sys_fsusage(path, &dspace, &dsize) == 0 && dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) { + DEBUG(3, ("print_job_start: disk space check failed.\n")); errno = ENOSPC; return -1; } @@ -852,18 +853,23 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /* for autoloaded printers, check that the printcap entry still exists */ if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) { + DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) )); errno = ENOENT; return -1; } /* Insure the maximum queue size is not violated */ if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) { + DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n", + print_queue_length(snum), lp_maxprintjobs(snum) )); errno = ENOSPC; return -1; } /* Insure the maximum print jobs in the system is not violated */ if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) { + DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n", + print_queue_length(snum), lp_totalprintjobs() )); errno = ENOSPC; return -1; } @@ -892,32 +898,27 @@ int print_job_start(struct current_user *user, int snum, char *jobname) /* lock the database */ tdb_lock_bystring(tdb, "INFO/nextjob"); - next_jobnum: next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); - if (next_jobid == -1) next_jobid = 1; + if (next_jobid == -1) + next_jobid = 1; for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) { - if (!print_job_exists(jobid)) break; + if (!print_job_exists(jobid)) + break; } if (jobid == next_jobid || !print_job_store(jobid, &pjob)) { + DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n", + jobid, next_jobid )); jobid = -1; goto fail; } tdb_store_int(tdb, "INFO/nextjob", jobid); - /* we have a job entry - now create the spool file - - we unlink first to cope with old spool files and also to beat - a symlink security hole - it allows us to use O_EXCL - There may be old spool files owned by other users lying around. - */ - slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%d", - path, PRINT_SPOOL_PREFIX, jobid); - if (unlink(pjob.filename) == -1 && errno != ENOENT) { - goto next_jobnum; - } - pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600); + /* we have a job entry - now create the spool file */ + slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%sXXXXXX", + path, PRINT_SPOOL_PREFIX); + pjob.fd = smb_mkstemp(pjob.filename); if (pjob.fd == -1) { if (errno == EACCES) { @@ -955,6 +956,8 @@ to open spool file %s.\n", pjob.filename)); } tdb_unlock_bystring(tdb, "INFO/nextjob"); + + DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); return -1; } @@ -990,6 +993,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) */ close(pjob->fd); pjob->fd = -1; + DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid )); goto fail; } @@ -1007,7 +1011,8 @@ BOOL print_job_end(int jobid, BOOL normal_close) ret = (*(current_printif->job_submit))(snum, pjob); - if (ret) goto fail; + if (ret) + goto fail; /* The print job has been sucessfully handed over to the back-end */ @@ -1016,11 +1021,13 @@ BOOL print_job_end(int jobid, BOOL normal_close) print_job_store(jobid, pjob); /* make sure the database is up to date */ - if (print_cache_expired(snum)) print_queue_update(snum); + if (print_cache_expired(snum)) + print_queue_update(snum); return True; fail: + /* The print job was not succesfully started. Cleanup */ /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); diff --git a/source/profile/profile.c b/source/profile/profile.c index dce1d78a9b6..20ad8531d88 100644 --- a/source/profile/profile.c +++ b/source/profile/profile.c @@ -22,8 +22,6 @@ #include "includes.h" -#include <sys/shm.h> - extern int DEBUGLEVEL; #define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6)) @@ -85,7 +83,7 @@ void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len) #else level = 0; #endif - DEBUG(1,("INFO: Received REQ_PROFILELEVEL message from PID %d\n",src)); + DEBUG(1,("INFO: Received REQ_PROFILELEVEL message from PID %u\n",(unsigned int)src)); message_send_pid(src, MSG_PROFILELEVEL, &level, sizeof(int), True); } diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c index cc79425eede..9c1f7299ea8 100644 --- a/source/rpc_client/cli_netlogon.c +++ b/source/rpc_client/cli_netlogon.c @@ -562,7 +562,7 @@ static BOOL modify_trust_password( char *domain, char *remote_machine, struct cli_state cli; ZERO_STRUCT(cli); - if(cli_initialise(&cli) == False) { + if(!cli_initialise(&cli)) { DEBUG(0,("modify_trust_password: unable to initialize client connection.\n")); return False; } diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c index 1ef8a78ea14..4bbbac17ed3 100644 --- a/source/rpc_client/cli_pipe.c +++ b/source/rpc_client/cli_pipe.c @@ -1,4 +1,3 @@ - /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -23,11 +22,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifdef SYSLOG -#undef SYSLOG -#endif - #include "includes.h" extern int DEBUGLEVEL; @@ -55,7 +49,6 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re int stream_offset = 0; int num_read; char *pdata; - uint32 err; int extra_data_size = ((int)*rdata_offset) + ((int)data_to_read) - (int)prs_data_size(rdata); DEBUG(5,("rpc_read: data_to_read: %u rdata offset: %u extra_data_size: %d\n", @@ -77,6 +70,9 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re do /* read data using SMBreadX */ { + uint32 ecode; + uint8 eclass; + if (size > (size_t)data_to_read) size = (size_t)data_to_read; @@ -85,8 +81,10 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); - if (cli_error(cli, NULL, &err, NULL)) { - DEBUG(0,("rpc_read: Error %u in cli_read\n", (unsigned int)err )); + if (cli_error(cli, &eclass, &ecode, NULL) && + (eclass != ERRDOS && ecode != ERRmoredata)) { + DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", + eclass, (unsigned int)ecode)); return False; } @@ -328,7 +326,6 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr char *rparam = NULL; uint32 rparam_len = 0; uint16 setup[2]; - uint32 err; BOOL first = True; BOOL last = True; RPC_HDR rhdr; @@ -338,16 +335,20 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr uint32 rdata_len = 0; uint32 current_offset = 0; - /* - * Create setup parameters - must be in native byte order. - */ + /* Create setup parameters - must be in native byte order. */ + setup[0] = cmd; setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, (int)cli->nt_pipe_fnum)); + DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, + (int)cli->nt_pipe_fnum)); - /* send the data: receive a response. */ - if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, + /* Send the RPC request and receive a response. For short RPC + calls (about 1024 bytes or so) the RPC request and response + appears in a SMBtrans request and response. Larger RPC + responses are received further on. */ + + if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ pdata, data_len, data_len, /* data, length, max */ @@ -358,9 +359,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr return False; } - /* - * Throw away returned params - we know we won't use them. - */ + /* Throw away returned params - we know we won't use them. */ if(rparam) { free(rparam); @@ -374,7 +373,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr } /* - * Give this memory as dynamically allocated to the return parse struct. + * Give this memory as dynamically allocated to the return parse + * struct. */ prs_give_memory(rdata, prdata, rdata_len, True); @@ -407,13 +407,15 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n", (unsigned int)len, (unsigned int)rdata_len )); - /* check if data to be sent back was too large for one SMB. */ - /* err status is only informational: the _real_ check is on the length */ + /* check if data to be sent back was too large for one SMBtrans */ + /* err status is only informational: the _real_ check is on the + length */ + if (len > 0) { /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ - /* - * Read the rest of the first response PDU. - */ + + /* Read the remaining part of the first response fragment */ + if (!rpc_read(cli, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; @@ -446,7 +448,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr } /* - * Read more fragments until we get the last one. + * Read more fragments using SMBreadX until we get one with the + * last bit set. */ while (!last) { @@ -454,6 +457,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr int num_read; char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN]; prs_struct hps; + uint8 eclass; + uint32 ecode; /* * First read the header of the next PDU. @@ -463,8 +468,10 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); - if (cli_error(cli, NULL, &err, NULL)) { - DEBUG(0,("rpc_api_pipe: cli_read error : %d\n", err )); + if (cli_error(cli, &eclass, &ecode, NULL) && + (eclass != ERRDOS && ecode != ERRmoredata)) { + DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", + eclass, ecode)); return False; } @@ -913,7 +920,7 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1 setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ /* send the data on \PIPE\ */ - if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, + if (cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* setup, length, max */ param, 2, 0, /* param, length, max */ NULL, 0, 1024, /* data, length, max */ @@ -971,9 +978,6 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * int i = 0; while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) { - DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n", - pipe_names[i].client_pipe , pipe_names[i].server_pipe )); - if ((strequal(pipe_name, pipe_names[i].client_pipe ))) { if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe )) { DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", @@ -1192,6 +1196,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) { int fnum; + SMB_ASSERT(cli->nt_pipe_fnum == 0); + if (cli->capabilities & CAP_NT_SMBS) { if ((fnum = cli_nt_create(cli, &(pipe_name[5]), DESIRED_ACCESS_PIPE)) == -1) { DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n", @@ -1253,4 +1259,5 @@ close the session void cli_nt_session_close(struct cli_state *cli) { cli_close(cli, cli->nt_pipe_fnum); + cli->nt_pipe_fnum = 0; } diff --git a/source/rpc_client/cli_spoolss_notify.c b/source/rpc_client/cli_spoolss_notify.c index 879a4f129fc..2f712f6adbc 100644 --- a/source/rpc_client/cli_spoolss_notify.c +++ b/source/rpc_client/cli_spoolss_notify.c @@ -48,7 +48,7 @@ BOOL spoolss_disconnect_from_client( struct cli_state *cli) BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine) { ZERO_STRUCTP(cli); - if(cli_initialise(cli) == False) { + if(!cli_initialise(cli)) { DEBUG(0,("connect_to_client: unable to initialize client connection.\n")); return False; } diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c index 98ef3fd0ee3..5abcfb9eef8 100644 --- a/source/rpc_parse/parse_lsa.c +++ b/source/rpc_parse/parse_lsa.c @@ -625,20 +625,6 @@ BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, return True; } -void lsa_free_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e) -{ - safe_free(r_e->uni_domain_name); - safe_free(r_e->hdr_domain_name); - safe_free(r_e->domain_sid); - - r_e->uni_domain_name = NULL; - r_e->hdr_domain_name = NULL; - r_e->domain_sid = NULL; - - r_e->num_domains = 0; - r_e->ptr_enum_domains = 0; -} - /******************************************************************* reads or writes a dom query structure. ********************************************************************/ @@ -758,7 +744,7 @@ static BOOL lsa_io_dom_query_6(char *desc, DOM_QUERY_6 *d_q, prs_struct *ps, int } /******************************************************************* - Reads or writes an LSA_Q_QUERY_INFO structure. + Reads or writes an LSA_R_QUERY_INFO structure. ********************************************************************/ BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, @@ -1295,3 +1281,73 @@ BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, in return True; } + +/******************************************************************* + Reads or writes an LSA_Q_UNK_GET_CONNUSER structure. +********************************************************************/ + +BOOL lsa_io_q_unk_get_connuser(char *desc, LSA_Q_UNK_GET_CONNUSER *q_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_q_unk_get_connuser"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_srvname", ps, depth, &q_c->ptr_srvname)) + return False; + + if(!smb_io_unistr2("uni2_srvname", &q_c->uni2_srvname, q_c->ptr_srvname, ps, depth)) /* server name to be looked up */ + return False; + + if(!prs_uint32("unk1", ps, depth, &q_c->unk1)) + return False; + if(!prs_uint32("unk2", ps, depth, &q_c->unk2)) + return False; + if(!prs_uint32("unk3", ps, depth, &q_c->unk3)) + return False; + + /* Don't bother to read or write at present... */ + return True; +} + +/******************************************************************* + Reads or writes an LSA_R_UNK_GET_CONNUSER structure. +********************************************************************/ + +BOOL lsa_io_r_unk_get_connuser(char *desc, LSA_R_UNK_GET_CONNUSER *r_c, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "lsa_io_r_unk_get_connuser"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_user_name", ps, depth, &r_c->ptr_user_name)) + return False; + if(!smb_io_unihdr("hdr_user_name", &r_c->hdr_user_name, ps, depth)) + return False; + if(!smb_io_unistr2("uni2_user_name", &r_c->uni2_user_name, r_c->ptr_user_name, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("unk1", ps, depth, &r_c->unk1)) + return False; + + if(!prs_uint32("ptr_dom_name", ps, depth, &r_c->ptr_dom_name)) + return False; + if(!smb_io_unihdr("hdr_dom_name", &r_c->hdr_dom_name, ps, depth)) + return False; + if(!smb_io_unistr2("uni2_dom_name", &r_c->uni2_dom_name, r_c->ptr_dom_name, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("status", ps, depth, &r_c->status)) + return False; + + return True; +} diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c index 81602a1dc40..4b118dd2b45 100644 --- a/source/rpc_parse/parse_misc.c +++ b/source/rpc_parse/parse_misc.c @@ -1457,6 +1457,37 @@ BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth) } /******************************************************************* + Create a UNISTR3. +********************************************************************/ + +void init_unistr3(UNISTR3 *str, const char *buf) +{ + size_t len; + + if (buf == NULL) { + str->uni_str_len=0; + str->str.buffer = NULL; + return; + } + + len = strlen(buf) + 1; + + str->uni_str_len=len; + + if (len < MAX_UNISTRLEN) + len = MAX_UNISTRLEN; + + len *= sizeof(uint16); + + str->str.buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len); + if (str->str.buffer == NULL) + smb_panic("init_unistr3: malloc fail\n"); + + /* store the string (null-terminated copy) */ + dos_struni2((char *)str->str.buffer, buf, len); +} + +/******************************************************************* Reads or writes a UNISTR3 structure. ********************************************************************/ diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c index 1fab8ce2971..587407b3dd3 100644 --- a/source/rpc_parse/parse_net.c +++ b/source/rpc_parse/parse_net.c @@ -217,14 +217,31 @@ BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, in } /******************************************************************* + Inits an NET_Q_LOGON_CTRL2 structure. +********************************************************************/ + +void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, char *srv_name, + uint32 query_level) +{ + DEBUG(5,("init_q_logon_ctrl2\n")); + + q_l->function_code = 0x01; + q_l->query_level = query_level; + q_l->switch_value = 0x01; + + init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1); +} + +/******************************************************************* Inits an NET_R_LOGON_CTRL2 structure. ********************************************************************/ -void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level, - uint32 flags, uint32 pdc_status, uint32 logon_attempts, - uint32 tc_status, char *trusted_domain_name) +void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level, + uint32 flags, uint32 pdc_status, + uint32 logon_attempts, uint32 tc_status, + char *trusted_domain_name) { - DEBUG(5,("make_r_logon_ctrl2\n")); + DEBUG(5,("init_r_logon_ctrl2\n")); r_l->switch_value = query_level; /* should only be 0x1 */ @@ -301,6 +318,113 @@ BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, in } /******************************************************************* + Reads or writes an NET_Q_LOGON_CTRL structure. +********************************************************************/ + +BOOL net_io_q_logon_ctrl(char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps, + int depth) +{ + prs_debug(ps, depth, desc, "net_io_q_logon_ctrl"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr ", ps, depth, &q_l->ptr)) + return False; + + if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("function_code", ps, depth, &q_l->function_code)) + return False; + if(!prs_uint32("query_level ", ps, depth, &q_l->query_level)) + return False; + + return True; +} + +/******************************************************************* + Inits an NET_Q_LOGON_CTRL structure. +********************************************************************/ + +void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, char *srv_name, + uint32 query_level) +{ + DEBUG(5,("init_q_logon_ctrl\n")); + + q_l->function_code = 0x01; /* ??? */ + q_l->query_level = query_level; + + init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1); +} + +/******************************************************************* + Inits an NET_R_LOGON_CTRL structure. +********************************************************************/ + +void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level, + uint32 flags, uint32 pdc_status) +{ + DEBUG(5,("init_r_logon_ctrl\n")); + + r_l->switch_value = query_level; /* should only be 0x1 */ + + switch (query_level) { + case 1: + r_l->ptr = 1; /* undocumented pointer */ + init_netinfo_1(&r_l->logon.info1, flags, pdc_status); + r_l->status = 0; + break; + default: + DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n", + r_l->switch_value)); + r_l->ptr = 0; /* undocumented pointer */ + + /* take a guess at an error code... */ + r_l->status = NT_STATUS_INVALID_INFO_CLASS; + break; + } +} + +/******************************************************************* + Reads or writes an NET_R_LOGON_CTRL structure. +********************************************************************/ + +BOOL net_io_r_logon_ctrl(char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps, + int depth) +{ + prs_debug(ps, depth, desc, "net_io_r_logon_ctrl"); + depth++; + + if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value)) + return False; + if(!prs_uint32("ptr ", ps, depth, &r_l->ptr)) + return False; + + if (r_l->ptr != 0) { + switch (r_l->switch_value) { + case 1: + if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth)) + return False; + break; + default: + DEBUG(2,("net_io_r_logon_ctrl: unsupported switch value %d\n", + r_l->switch_value)); + break; + } + } + + if(!prs_uint32("status ", ps, depth, &r_l->status)) + return False; + + return True; +} + +/******************************************************************* Inits an NET_R_TRUST_DOM_LIST structure. ********************************************************************/ @@ -309,7 +433,7 @@ void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t, { int i = 0; - DEBUG(5,("make_r_trust_dom\n")); + DEBUG(5,("init_r_trust_dom\n")); for (i = 0; i < MAX_TRUST_DOMS; i++) { r_t->uni_trust_dom_name[i].uni_str_len = 0; @@ -410,7 +534,7 @@ void init_q_req_chal(NET_Q_REQ_CHAL *q_c, char *logon_srv, char *logon_clnt, DOM_CHAL *clnt_chal) { - DEBUG(5,("make_q_req_chal: %d\n", __LINE__)); + DEBUG(5,("init_q_req_chal: %d\n", __LINE__)); q_c->undoc_buffer = 1; /* don't know what this buffer is */ @@ -419,7 +543,7 @@ void init_q_req_chal(NET_Q_REQ_CHAL *q_c, memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); - DEBUG(5,("make_q_req_chal: %d\n", __LINE__)); + DEBUG(5,("init_q_req_chal: %d\n", __LINE__)); } /******************************************************************* @@ -486,6 +610,61 @@ BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int dept /******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth) +{ + int old_align; + if (q_a == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_q_auth"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */ + return False; + /* client challenge is _not_ aligned */ + old_align = ps->align; + ps->align = 0; + if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) { + /* client-calculated credentials */ + ps->align = old_align; + return False; + } + ps->align = old_align; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth) +{ + if (r_a == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_r_auth"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */ + return False; + + if(!prs_uint32("status", ps, depth, &r_a->status)) + return False; + + return True; +} + +/******************************************************************* Inits a NET_Q_AUTH_2 struct. ********************************************************************/ @@ -569,7 +748,7 @@ BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth) void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16]) { - DEBUG(5,("make_q_srv_pwset\n")); + DEBUG(5,("init_q_srv_pwset\n")); init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred); @@ -681,7 +860,7 @@ void init_id_info1(NET_ID_INFO_1 *id, char *domain_name, unsigned char lm_owf[16]; unsigned char nt_owf[16]; - DEBUG(5,("make_id_info1: %d\n", __LINE__)); + DEBUG(5,("init_id_info1: %d\n", __LINE__)); id->ptr_id_info1 = 1; @@ -707,9 +886,9 @@ void init_id_info1(NET_ID_INFO_1 *id, char *domain_name, memcpy(key, sess_key, 8); memcpy(lm_owf, lm_cypher, 16); - SamOEMhash(lm_owf, key, False); + SamOEMhash(lm_owf, key, 16); memcpy(nt_owf, nt_cypher, 16); - SamOEMhash(nt_owf, key, False); + SamOEMhash(nt_owf, key, 16); #ifdef DEBUG_PASSWORD DEBUG(100,("encrypt of lm owf password:")); diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c index 20536c91b47..9711eee4524 100644 --- a/source/rpc_parse/parse_samr.c +++ b/source/rpc_parse/parse_samr.c @@ -23,7 +23,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include "includes.h" #include "rpc_parse.h" #include "nterr.h" @@ -1387,7 +1386,7 @@ BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e, inits a SAM_DISPINFO_1 structure. ********************************************************************/ -void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) { @@ -1404,7 +1403,19 @@ void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries, DEBUG(5, ("init_sam_dispinfo_1: max_entries: %d max_dsize: 0x%x\n", max_entries, max_data_size)); + sam->sam=(SAM_ENTRY1 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY1)); + if (!sam->sam) + return NT_STATUS_NO_MEMORY; + + sam->str=(SAM_STR1 *)talloc(ctx, max_entries*sizeof(SAM_STR1)); + if (!sam->str) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(sam->sam); + ZERO_STRUCTP(sam->str); + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) { + DEBUG(5, ("init_sam_dispinfo_1: entry: %d\n",i)); len_sam_name = pass[i].uni_user_name.uni_str_len; len_sam_full = pass[i].uni_full_name.uni_str_len; len_sam_desc = pass[i].uni_acct_desc.uni_str_len; @@ -1413,6 +1424,10 @@ void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries, len_sam_name, len_sam_full, len_sam_desc, pass[i].user_rid, pass[i].acb_info); + ZERO_STRUCTP(&sam->str[i].uni_acct_name); + ZERO_STRUCTP(&sam->str[i].uni_full_name); + ZERO_STRUCTP(&sam->str[i].uni_acct_desc); + copy_unistr2(&sam->str[i].uni_acct_name, &pass[i].uni_user_name); copy_unistr2(&sam->str[i].uni_full_name, &pass[i].uni_full_name); copy_unistr2(&sam->str[i].uni_acct_desc, &pass[i].uni_acct_desc); @@ -1423,6 +1438,8 @@ void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries, *num_entries = i; *data_size = dsize; + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1435,16 +1452,28 @@ static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 * sam, { uint32 i; - if (sam == NULL) - return False; - prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_1"); depth++; if(!prs_align(ps)) return False; - SMB_ASSERT_ARRAY(sam->sam, num_entries); + if (UNMARSHALLING(ps) && num_entries > 0) { + + if ((sam->sam = (SAM_ENTRY1 *) + prs_alloc_mem(ps, sizeof(SAM_ENTRY1) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_ENTRY1\n")); + return False; + } + + if ((sam->str = (SAM_STR1 *) + prs_alloc_mem(ps, sizeof(SAM_STR1) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_STR1\n")); + return False; + } + } for (i = 0; i < num_entries; i++) { if(!sam_io_sam_entry1("", &sam->sam[i], ps, depth)) @@ -1466,7 +1495,7 @@ static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 * sam, inits a SAM_DISPINFO_2 structure. ********************************************************************/ -void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) { @@ -1482,6 +1511,15 @@ void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries, max_entries = *num_entries; max_data_size = *data_size; + if (!(sam->sam=(SAM_ENTRY2 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY2)))) + return NT_STATUS_NO_MEMORY; + + if (!(sam->str=(SAM_STR2 *)talloc(ctx, max_entries*sizeof(SAM_STR2)))) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(sam->sam); + ZERO_STRUCTP(sam->str); + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) { len_sam_name = pass[i].uni_user_name.uni_str_len; len_sam_desc = pass[i].uni_acct_desc.uni_str_len; @@ -1490,10 +1528,11 @@ void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries, len_sam_name, len_sam_desc, pass[i].user_rid, pass[i].acb_info); - copy_unistr2(&sam->str[i].uni_srv_name, - &pass[i].uni_user_name); - copy_unistr2(&sam->str[i].uni_srv_desc, - &pass[i].uni_acct_desc); + ZERO_STRUCTP(&sam->str[i].uni_srv_name); + ZERO_STRUCTP(&sam->str[i].uni_srv_desc); + + copy_unistr2(&sam->str[i].uni_srv_name, &pass[i].uni_user_name); + copy_unistr2(&sam->str[i].uni_srv_desc, &pass[i].uni_acct_desc); dsize += sizeof(SAM_ENTRY2); dsize += len_sam_name + len_sam_desc; @@ -1501,6 +1540,8 @@ void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries, *num_entries = i; *data_size = dsize; + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1522,7 +1563,22 @@ static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 * sam, if(!prs_align(ps)) return False; - SMB_ASSERT_ARRAY(sam->sam, num_entries); + if (UNMARSHALLING(ps) && num_entries > 0) { + + if ((sam->sam = (SAM_ENTRY2 *) + prs_alloc_mem(ps, sizeof(SAM_ENTRY2) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_ENTRY2\n")); + return False; + } + + if ((sam->str = (SAM_STR2 *) + prs_alloc_mem(ps, sizeof(SAM_STR2) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_STR2\n")); + return False; + } + } for (i = 0; i < num_entries; i++) { if(!sam_io_sam_entry2("", &sam->sam[i], ps, depth)) @@ -1543,7 +1599,7 @@ static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 * sam, inits a SAM_DISPINFO_3 structure. ********************************************************************/ -void init_sam_dispinfo_3(SAM_DISPINFO_3 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, DOMAIN_GRP * grp) { @@ -1559,6 +1615,15 @@ void init_sam_dispinfo_3(SAM_DISPINFO_3 * sam, uint32 *num_entries, max_entries = *num_entries; max_data_size = *data_size; + if (!(sam->sam=(SAM_ENTRY3 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY3)))) + return NT_STATUS_NO_MEMORY; + + if (!(sam->str=(SAM_STR3 *)talloc(ctx, max_entries*sizeof(SAM_STR3)))) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(sam->sam); + ZERO_STRUCTP(sam->str); + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) { len_sam_name = strlen(grp[i].name); len_sam_desc = strlen(grp[i].comment); @@ -1575,6 +1640,8 @@ void init_sam_dispinfo_3(SAM_DISPINFO_3 * sam, uint32 *num_entries, *num_entries = i; *data_size = dsize; + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1596,7 +1663,22 @@ static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 * sam, if(!prs_align(ps)) return False; - SMB_ASSERT_ARRAY(sam->sam, num_entries); + if (UNMARSHALLING(ps) && num_entries > 0) { + + if ((sam->sam = (SAM_ENTRY3 *) + prs_alloc_mem(ps, sizeof(SAM_ENTRY3) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_ENTRY3\n")); + return False; + } + + if ((sam->str = (SAM_STR3 *) + prs_alloc_mem(ps, sizeof(SAM_STR3) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_STR3\n")); + return False; + } + } for (i = 0; i < num_entries; i++) { if(!sam_io_sam_entry3("", &sam->sam[i], ps, depth)) @@ -1617,7 +1699,7 @@ static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 * sam, inits a SAM_DISPINFO_4 structure. ********************************************************************/ -void init_sam_dispinfo_4(SAM_DISPINFO_4 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) { @@ -1634,16 +1716,22 @@ void init_sam_dispinfo_4(SAM_DISPINFO_4 * sam, uint32 *num_entries, max_entries = *num_entries; max_data_size = *data_size; + if (!(sam->sam=(SAM_ENTRY4 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY4)))) + return NT_STATUS_NO_MEMORY; + + if (!(sam->str=(SAM_STR4 *)talloc(ctx, max_entries*sizeof(SAM_STR4)))) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(sam->sam); + ZERO_STRUCTP(sam->str); + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) { len_sam_name = pass[i].uni_user_name.uni_str_len; - init_sam_entry4(&sam->sam[i], start_idx + i + 1, - len_sam_name); - - unistr2_to_ascii(sam_name, &pass[i].uni_user_name, - sizeof(sam_name)); - init_string2(&sam->str[i].acct_name, sam_name, - len_sam_name); + init_sam_entry4(&sam->sam[i], start_idx + i + 1, len_sam_name); + + unistr2_to_ascii(sam_name, &pass[i].uni_user_name, sizeof(sam_name)); + init_string2(&sam->str[i].acct_name, sam_name, len_sam_name); dsize += sizeof(SAM_ENTRY4); dsize += len_sam_name; @@ -1651,6 +1739,8 @@ void init_sam_dispinfo_4(SAM_DISPINFO_4 * sam, uint32 *num_entries, *num_entries = i; *data_size = dsize; + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1672,7 +1762,22 @@ static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam, if(!prs_align(ps)) return False; - SMB_ASSERT_ARRAY(sam->sam, num_entries); + if (UNMARSHALLING(ps) && num_entries > 0) { + + if ((sam->sam = (SAM_ENTRY4 *) + prs_alloc_mem(ps, sizeof(SAM_ENTRY4) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_ENTRY4\n")); + return False; + } + + if ((sam->str = (SAM_STR4 *) + prs_alloc_mem(ps, sizeof(SAM_STR4) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_STR4\n")); + return False; + } + } for (i = 0; i < num_entries; i++) { if(!sam_io_sam_entry4("", &sam->sam[i], ps, depth)) @@ -1694,7 +1799,7 @@ static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam, inits a SAM_DISPINFO_5 structure. ********************************************************************/ -void init_sam_dispinfo_5(SAM_DISPINFO_5 * sam, uint32 *num_entries, +uint32 init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 *num_entries, uint32 *data_size, uint32 start_idx, DOMAIN_GRP * grp) { @@ -1710,14 +1815,20 @@ void init_sam_dispinfo_5(SAM_DISPINFO_5 * sam, uint32 *num_entries, max_entries = *num_entries; max_data_size = *data_size; + if (!(sam->sam=(SAM_ENTRY5 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY5)))) + return NT_STATUS_NO_MEMORY; + + if (!(sam->str=(SAM_STR5 *)talloc(ctx, max_entries*sizeof(SAM_STR5)))) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(sam->sam); + ZERO_STRUCTP(sam->str); + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) { len_sam_name = strlen(grp[i].name); - init_sam_entry5(&sam->sam[i], start_idx + i + 1, - len_sam_name); - - init_string2(&sam->str[i].grp_name, grp[i].name, - len_sam_name); + init_sam_entry5(&sam->sam[i], start_idx + i + 1, len_sam_name); + init_string2(&sam->str[i].grp_name, grp[i].name, len_sam_name); dsize += sizeof(SAM_ENTRY5); dsize += len_sam_name; @@ -1725,6 +1836,8 @@ void init_sam_dispinfo_5(SAM_DISPINFO_5 * sam, uint32 *num_entries, *num_entries = i; *data_size = dsize; + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1746,7 +1859,22 @@ static BOOL sam_io_sam_dispinfo_5(char *desc, SAM_DISPINFO_5 * sam, if(!prs_align(ps)) return False; - SMB_ASSERT_ARRAY(sam->sam, num_entries); + if (UNMARSHALLING(ps) && num_entries > 0) { + + if ((sam->sam = (SAM_ENTRY5 *) + prs_alloc_mem(ps, sizeof(SAM_ENTRY5) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_ENTRY5\n")); + return False; + } + + if ((sam->str = (SAM_STR5 *) + prs_alloc_mem(ps, sizeof(SAM_STR5) * + num_entries)) == NULL) { + DEBUG(0, ("out of memory allocating SAM_STR5\n")); + return False; + } + } for (i = 0; i < num_entries; i++) { if(!sam_io_sam_entry5("", &sam->sam[i], ps, depth)) @@ -2047,29 +2175,32 @@ BOOL samr_io_group_info4(char *desc, GROUP_INFO4 * gr4, reads or writes a structure. ********************************************************************/ -static BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR * ctr, +static BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR **ctr, prs_struct *ps, int depth) { - if (ctr == NULL) + if (UNMARSHALLING(ps)) + *ctr = (GROUP_INFO_CTR *)prs_alloc_mem(ps,sizeof(GROUP_INFO_CTR)); + + if (*ctr == NULL) return False; prs_debug(ps, depth, desc, "samr_group_info_ctr"); depth++; - if(!prs_uint16("switch_value1", ps, depth, &ctr->switch_value1)) + if(!prs_uint16("switch_value1", ps, depth, &(*ctr)->switch_value1)) return False; - if(!prs_uint16("switch_value2", ps, depth, &ctr->switch_value2)) + if(!prs_uint16("switch_value2", ps, depth, &(*ctr)->switch_value2)) return False; - switch (ctr->switch_value1) { + switch ((*ctr)->switch_value1) { case 1: if(!samr_io_group_info1("group_info1", - &ctr->group.info1, ps, depth)) + &(*ctr)->group.info1, ps, depth)) return False; break; case 4: if(!samr_io_group_info4("group_info4", - &ctr->group.info4, ps, depth)) + &(*ctr)->group.info4, ps, depth)) return False; break; default: @@ -2395,7 +2526,7 @@ BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e, if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth)) return False; - if(!samr_group_info_ctr("ctr", q_e->ctr, ps, depth)) + if(!samr_group_info_ctr("ctr", &q_e->ctr, ps, depth)) return False; return True; @@ -2507,7 +2638,7 @@ BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u, return False; if (r_u->ptr != 0) { - if(!samr_group_info_ctr("ctr", r_u->ctr, ps, depth)) + if(!samr_group_info_ctr("ctr", &r_u->ctr, ps, depth)) return False; } @@ -3594,15 +3725,12 @@ inits a SAMR_Q_OPEN_ALIAS structure. ********************************************************************/ void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, POLICY_HND *pol, - uint32 unknown_0, uint32 rid) + uint32 access_mask, uint32 rid) { DEBUG(5, ("init_samr_q_open_alias\n")); q_u->dom_pol = *pol; - - /* example values: 0x0000 0008 */ - q_u->unknown_0 = unknown_0; - + q_u->access_mask = access_mask; q_u->rid_alias = rid; } @@ -3625,7 +3753,7 @@ BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS * q_u, if(!smb_io_pol_hnd("domain_pol", &q_u->dom_pol, ps, depth)) return False; - if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0)) + if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask)) return False; if(!prs_uint32("rid_alias", ps, depth, &q_u->rid_alias)) return False; @@ -3678,6 +3806,8 @@ void init_samr_q_lookup_rids(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_RIDS * q_u, if (q_u->rid == NULL) { q_u->num_rids1 = 0; q_u->num_rids2 = 0; + } else { + memcpy(q_u->rid, rid, num_rids * sizeof(q_u->rid[0])); } } @@ -4289,7 +4419,7 @@ BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u, inits a SAMR_Q_LOOKUP_NAMES structure. ********************************************************************/ -void init_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u, +uint32 init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u, POLICY_HND *pol, uint32 flags, uint32 num_names, char **name) { @@ -4304,11 +4434,19 @@ void init_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u, q_u->ptr = 0; q_u->num_names2 = num_names; + if (!(q_u->hdr_name = (UNIHDR *)talloc_zero(ctx, num_names * sizeof(UNIHDR)))) + return NT_STATUS_NO_MEMORY; + + if (!(q_u->uni_name = (UNISTR2 *)talloc_zero(ctx, num_names * sizeof(UNISTR2)))) + return NT_STATUS_NO_MEMORY; + for (i = 0; i < num_names; i++) { int len_name = name[i] != NULL ? strlen(name[i]) : 0; init_uni_hdr(&q_u->hdr_name[i], len_name); /* unicode header for user_name */ init_unistr2(&q_u->uni_name[i], name[i], len_name); /* unicode string for machine account */ } + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -4344,7 +4482,14 @@ BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u, if(!prs_uint32("num_names2", ps, depth, &q_u->num_names2)) return False; - SMB_ASSERT_ARRAY(q_u->hdr_name, q_u->num_names2); + if (UNMARSHALLING(ps) && (q_u->num_names2 != 0)) { + q_u->hdr_name = (UNIHDR *)prs_alloc_mem(ps, sizeof(UNIHDR) * + q_u->num_names2); + q_u->uni_name = (UNISTR2 *)prs_alloc_mem(ps, sizeof(UNISTR2) * + q_u->num_names2); + if (!q_u->hdr_name || !q_u->uni_name) + return False; + } for (i = 0; i < q_u->num_names2; i++) { if(!smb_io_unihdr("", &q_u->hdr_name[i], ps, depth)) @@ -4363,7 +4508,7 @@ BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u, inits a SAMR_R_LOOKUP_NAMES structure. ********************************************************************/ -void init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u, +uint32 init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u, uint32 num_rids, uint32 *rid, uint32 *type, uint32 status) @@ -4381,8 +4526,10 @@ void init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u, r_u->ptr_rids = 1; r_u->num_rids2 = num_rids; - r_u->rids = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids); - r_u->types = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids); + if (!(r_u->rids = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids))) + return NT_STATUS_NO_MEMORY; + if (!(r_u->types = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids))) + return NT_STATUS_NO_MEMORY; if (!r_u->rids || !r_u->types) goto empty; @@ -4407,6 +4554,8 @@ void init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u, } r_u->status = status; + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -4985,10 +5134,9 @@ static BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 * usr, *************************************************************************/ -void init_sam_user_info24(SAM_USER_INFO_24 * usr, - char newpass[516], uint16 passlen) +void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516]) { - DEBUG(10, ("init_sam_user_info24: passlen: %d\n", passlen)); + DEBUG(10, ("init_sam_user_info24:\n")); memcpy(usr->pass, newpass, sizeof(usr->pass)); } @@ -5011,6 +5159,9 @@ static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 * usr, if(!prs_uint8s(False, "password", ps, depth, usr->pass, sizeof(usr->pass))) return False; + if(!prs_align(ps)) + return False; + return True; } @@ -5325,6 +5476,126 @@ static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 * usr, return True; } +/******************************************************************* + reads or writes a structure. + NB. This structure is *definately* incorrect. It's my best guess + currently for W2K SP2. The password field is encrypted in a different + way than normal... And there are definately other problems. JRA. +********************************************************************/ + +static BOOL sam_io_user_info25(char *desc, SAM_USER_INFO_25 * usr, prs_struct *ps, int depth) +{ + if (usr == NULL) + return False; + + prs_debug(ps, depth, desc, "sam_io_user_info23"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_time("logon_time ", &usr->logon_time, ps, depth)) + return False; + if(!smb_io_time("logoff_time ", &usr->logoff_time, ps, depth)) + return False; + if(!smb_io_time("kickoff_time ", &usr->kickoff_time, ps, depth)) + return False; + if(!smb_io_time("pass_last_set_time ", &usr->pass_last_set_time, ps, depth)) + return False; + if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth)) + return False; + if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth)) + return False; + + if(!smb_io_unihdr("hdr_user_name ", &usr->hdr_user_name, ps, depth)) /* username unicode string header */ + return False; + if(!smb_io_unihdr("hdr_full_name ", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */ + return False; + if(!smb_io_unihdr("hdr_home_dir ", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */ + return False; + if(!smb_io_unihdr("hdr_dir_drive ", &usr->hdr_dir_drive, ps, depth)) /* home directory drive */ + return False; + if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */ + return False; + if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */ + return False; + if(!smb_io_unihdr("hdr_acct_desc ", &usr->hdr_acct_desc, ps, depth)) /* account desc */ + return False; + if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth)) /* wkstas user can log on from */ + return False; + if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth)) /* unknown string */ + return False; + if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth)) /* wkstas user can log on from */ + return False; + + if(!prs_uint8s(False, "lm_pwd ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd))) + return False; + if(!prs_uint8s(False, "nt_pwd ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd))) + return False; + + if(!prs_uint32("user_rid ", ps, depth, &usr->user_rid)) /* User ID */ + return False; + if(!prs_uint32("group_rid ", ps, depth, &usr->group_rid)) /* Group ID */ + return False; + if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info)) + return False; + + if(!prs_uint32s(False, "unknown_6 ", ps, depth, usr->unknown_6, 6)) + return False; + + if(!prs_uint8s(False, "password ", ps, depth, usr->pass, sizeof(usr->pass))) + return False; + + /* here begins pointed-to data */ + + if(!smb_io_unistr2("uni_user_name ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */ + return False; + + if(!smb_io_unistr2("uni_full_name ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */ + return False; + + if(!smb_io_unistr2("uni_home_dir ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */ + return False; + + if(!smb_io_unistr2("uni_dir_drive ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */ + return False; + + if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */ + return False; + + if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */ + return False; + + if(!smb_io_unistr2("uni_acct_desc ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user desc unicode string */ + return False; + + if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth)) /* worksations user can log on from */ + return False; + + if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str.buffer, ps, depth)) /* unknown string */ + return False; + + if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth)) + return False; + +#if 0 /* JRA - unknown... */ + /* ok, this is only guess-work (as usual) */ + if (usr->ptr_logon_hrs) { + if(!prs_uint32("unknown_6 ", ps, depth, &usr->unknown_6)) + return False; + if(!prs_uint32("padding4 ", ps, depth, &usr->padding4)) + return False; + if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth)) + return False; + } else if (UNMARSHALLING(ps)) { + usr->unknown_6 = 0; + usr->padding4 = 0; + } +#endif + + return True; +} + /************************************************************************* init_sam_user_info21W @@ -5715,12 +5986,12 @@ void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key, switch (switch_value) { case 0x18: - SamOEMhash(ctr->info.id24->pass, sess_key, 1); + SamOEMhash(ctr->info.id24->pass, sess_key, 516); dump_data(100, (char *)sess_key, 16); dump_data(100, (char *)ctr->info.id24->pass, 516); break; case 0x17: - SamOEMhash(ctr->info.id23->pass, sess_key, 1); + SamOEMhash(ctr->info.id23->pass, sess_key, 516); dump_data(100, (char *)sess_key, 16); dump_data(100, (char *)ctr->info.id23->pass, 516); break; @@ -5820,6 +6091,16 @@ static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR **ppctr, } ret = sam_io_user_info24("", ctr->info.id24, ps, depth); break; + case 25: + if (UNMARSHALLING(ps)) + ctr->info.id25 = (SAM_USER_INFO_25 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_25)); + + if (ctr->info.id25 == NULL) { + DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n")); + return False; + } + ret = sam_io_user_info25("", ctr->info.id25, ps, depth); + break; default: DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value)); ret = False; @@ -5974,8 +6255,8 @@ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u, switch (switch_value) { case 0x12: - SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 0); - SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 0); + SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 16); + SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 16); dump_data(100, (char *)sess_key, 16); dump_data(100, (char *)ctr->info.id12->lm_pwd, 16); dump_data(100, (char *)ctr->info.id12->nt_pwd, 16); diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c index e5d3a6ce43c..b202c2a3566 100644 --- a/source/rpc_parse/parse_sec.c +++ b/source/rpc_parse/parse_sec.c @@ -135,7 +135,14 @@ SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *a dst->num_aces = num_aces; dst->size = 8; - if((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces )) == NULL) { + /* Now we need to return a non-NULL address for the ace list even + if the number of aces required is zero. This is because there + is a distinct difference between a NULL ace and an ace with zero + entries in it. This is achieved by always making the number of + bytes allocated by talloc() positive. Heh. */ + + if((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces + 1)) + == NULL) { return NULL; } @@ -204,9 +211,13 @@ BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth) if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces)) return False; - if (UNMARSHALLING(ps) && psa->num_aces != 0) { - /* reading */ - if((psa->ace = (SEC_ACE *)prs_alloc_mem(ps,sizeof(psa->ace[0]) * psa->num_aces)) == NULL) + if (UNMARSHALLING(ps)) { + /* + * Even if the num_aces is zero, allocate memory as there's a difference + * between a non-present DACL (allow all access) and a DACL with no ACE's + * (allow no access). + */ + if((psa->ace = (SEC_ACE *)prs_alloc_mem(ps,sizeof(psa->ace[0]) * (psa->num_aces+1))) == NULL) return False; } diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index ff3e53273a0..2b81a7708c0 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -761,6 +761,7 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, * init a structure. ********************************************************************/ BOOL make_spoolss_q_addprinterex( + TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, const char *srv_name, const char* clientname, @@ -783,7 +784,7 @@ BOOL make_spoolss_q_addprinterex( { case 2: /* init q_u->info.info2 from *info */ - if (!make_spoolss_printer_info_2(&q_u->info.info_2, ctr->printers_2)) + if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) { DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n")); return False; @@ -818,6 +819,7 @@ create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct *******************************************************************/ BOOL make_spoolss_printer_info_2( + TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, PRINTER_INFO_2 *info ) @@ -826,8 +828,7 @@ BOOL make_spoolss_printer_info_2( SPOOL_PRINTER_INFO_LEVEL_2 *inf; /* allocate the necessary memory */ - inf = (SPOOL_PRINTER_INFO_LEVEL_2*)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2)); - if (!spool_info2) + if (!(inf=(SPOOL_PRINTER_INFO_LEVEL_2*)talloc(mem_ctx, sizeof(SPOOL_PRINTER_INFO_LEVEL_2)))) { DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n")); return False; @@ -908,6 +909,31 @@ BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_ } /******************************************************************* + * init a structure. + ********************************************************************/ +BOOL make_spoolss_q_deleteprinterdriver( + TALLOC_CTX *mem_ctx, + SPOOL_Q_DELETEPRINTERDRIVER *q_u, + const char *server, + const char* arch, + const char* driver +) +{ + DEBUG(5,("make_spoolss_q_deleteprinterdriver\n")); + + q_u->server_ptr = (server!=NULL)?1:0; + + /* these must be NULL terminated or else NT4 will + complain about invalid parameters --jerry */ + init_unistr2(&q_u->server, server, strlen(server)+1); + init_unistr2(&q_u->arch, arch, strlen(arch)+1); + init_unistr2(&q_u->driver, driver, strlen(driver)+1); + + + return True; +} + +/******************************************************************* * write a structure. * called from static spoolss_r_open_printer_ex (srv_spoolss.c) * called from spoolss_open_printer_ex (cli_spoolss.c) @@ -1150,6 +1176,58 @@ BOOL spoolss_io_r_deleteprinter(char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_stru return True; } + +/******************************************************************* + * read a structure. + * called from api_spoolss_deleteprinterdriver (srv_spoolss.c) + * called from spoolss_deleteprinterdriver (cli_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_q_deleteprinterdriver(char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver"); + depth++; + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr)) + return False; + if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth)) + return False; + if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth)) + return False; + + + return True; +} + + +/******************************************************************* + * write a structure. + ********************************************************************/ +BOOL spoolss_io_r_deleteprinterdriver(char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; + + return True; +} + + + /******************************************************************* * read a structure. * called from static spoolss_q_closeprinter (srv_spoolss.c) @@ -3256,9 +3334,14 @@ BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, * init a structure. ********************************************************************/ -BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, - fstring servername, uint32 level, - NEW_BUFFER *buffer, uint32 offered) +BOOL make_spoolss_q_enumprinters( + SPOOL_Q_ENUMPRINTERS *q_u, + uint32 flags, + fstring servername, + uint32 level, + NEW_BUFFER *buffer, + uint32 offered +) { q_u->flags=flags; @@ -3420,6 +3503,7 @@ BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps ********************************************************************/ BOOL make_spoolss_q_getprinter( + TALLOC_CTX *mem_ctx, SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, @@ -3444,6 +3528,7 @@ BOOL make_spoolss_q_getprinter( * init a structure. ********************************************************************/ BOOL make_spoolss_q_setprinter( + TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, @@ -3474,7 +3559,7 @@ BOOL make_spoolss_q_setprinter( info->printers_2->devmode = NULL; info->printers_2->secdesc = NULL; - make_spoolss_printer_info_2 (&q_u->info.info_2, info->printers_2); + make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2); #if 0 /* JERRY TEST */ q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF)); if (!q_u->secdesc_ctr) @@ -3483,13 +3568,13 @@ BOOL make_spoolss_q_setprinter( q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; q_u->secdesc_ctr->sec = secdesc; - + q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0; q_u->devmode_ctr.size = sizeof(DEVICEMODE) + (3*sizeof(uint32)); q_u->devmode_ctr.devmode = devmode; #else q_u->secdesc_ctr = NULL; - + q_u->devmode_ctr.devmode_ptr = 0; q_u->devmode_ctr.size = 0; q_u->devmode_ctr.devmode = NULL; @@ -4700,6 +4785,7 @@ BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LE ******************************************************************/ BOOL make_spoolss_q_addprinterdriver( + TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, uint32 level, @@ -4718,7 +4804,7 @@ BOOL make_spoolss_q_addprinterdriver( { /* info level 3 is supported by Windows 95/98, WinNT and Win2k */ case 3 : - make_spoolss_driver_info_3(&q_u->info.info_3, info->info3); + make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3); break; /* info level 6 is supported by WinME and Win2k */ @@ -4735,6 +4821,7 @@ BOOL make_spoolss_q_addprinterdriver( } BOOL make_spoolss_driver_info_3( + TALLOC_CTX *mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info, DRIVER_INFO_3 *info3 ) @@ -4745,11 +4832,8 @@ BOOL make_spoolss_driver_info_3( BOOL null_char = False; SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf; - inf = (SPOOL_PRINTER_DRIVER_INFO_LEVEL_3*) - malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)); - if (!inf) + if (!(inf=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3*)talloc_zero(mem_ctx, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))) return False; - memset (inf, 0x0, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)); inf->cversion = info3->version; inf->name_ptr = (info3->name.buffer!=NULL)?1:0; @@ -4793,7 +4877,7 @@ BOOL make_spoolss_driver_info_3( } inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0; inf->dependentfilessize = len; - if(!make_spoolss_buffer5(&inf->dependentfiles, len, info3->dependentfiles)) + if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) { safe_free (inf); return False; @@ -4808,18 +4892,21 @@ BOOL make_spoolss_driver_info_3( make a BUFFER5 struct from a uint16* ******************************************************************/ -BOOL make_spoolss_buffer5(BUFFER5 *buf5, uint32 len, uint16 *src) +BOOL make_spoolss_buffer5( + TALLOC_CTX *mem_ctx, + BUFFER5 *buf5, + uint32 len, + uint16 *src +) { buf5->buf_len = len; - if((buf5->buffer=(uint16*)malloc(sizeof(uint16)*len)) == NULL) + if((buf5->buffer=(uint16*)talloc_memdup(mem_ctx, src, sizeof(uint16)*len)) == NULL) { DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n")); return False; } - memcpy(buf5->buffer, src, sizeof(uint16)*len); - return True; } @@ -5168,6 +5255,57 @@ BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q /******************************************************************* ********************************************************************/ +BOOL spoolss_io_q_addprintprocessor(char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr)) + return False; + if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("path", &q_u->path, True, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("name", &q_u->name, True, ps, depth)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ + +BOOL spoolss_io_r_addprintprocessor(char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ + BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes"); @@ -5407,12 +5545,14 @@ BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st case 0x3: case 0x4: case 0x7: - if (UNMARSHALLING(ps)) - q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8)); - if(q_u->data == NULL) - return False; - if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len)) - return False; + if (q_u->max_len) { + if (UNMARSHALLING(ps)) + q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8)); + if(q_u->data == NULL) + return False; + if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len)) + return False; + } if(!prs_align(ps)) return False; break; diff --git a/source/rpc_parse/parse_srv.c b/source/rpc_parse/parse_srv.c index 61d2ff7ba2a..637b8342660 100644 --- a/source/rpc_parse/parse_srv.c +++ b/source/rpc_parse/parse_srv.c @@ -1,4 +1,3 @@ - /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -280,18 +279,27 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps, Inits a SH_INFO_502_STR structure ********************************************************************/ -void init_srv_share_info502_str(SH_INFO_502_STR *sh502, +void init_srv_share_info502_str(SH_INFO_502_STR *sh502str, + SH_INFO_502 *ptrs, char *net_name, char *remark, char *path, char *passwd, SEC_DESC *psd, size_t sd_size) { DEBUG(5,("init_srv_share_info502_str\n")); - init_unistr2(&sh502->uni_netname, net_name, strlen(net_name)+1); - init_unistr2(&sh502->uni_remark, remark, strlen(remark)+1); - init_unistr2(&sh502->uni_path, path, strlen(path)+1); - init_unistr2(&sh502->uni_passwd, passwd, strlen(passwd)+1); - sh502->sd = psd; - sh502->sd_size = sd_size; + sh502str->ptrs = ptrs; + + if(sh502str->ptrs->ptr_netname) + init_unistr2(&sh502str->uni_netname, net_name, strlen(net_name)+1); + if(sh502str->ptrs->ptr_remark) + init_unistr2(&sh502str->uni_remark, remark, strlen(remark)+1); + if(sh502str->ptrs->ptr_path) + init_unistr2(&sh502str->uni_path, path, strlen(path)+1); + if(sh502str->ptrs->ptr_passwd) + init_unistr2(&sh502str->uni_passwd, passwd, strlen(passwd)+1); + if(sh502str->ptrs->ptr_sd) { + sh502str->sd = psd; + sh502str->sd_size = sd_size; + } } /******************************************************************* @@ -308,31 +316,45 @@ static BOOL srv_io_share_info502_str(char *desc, SH_INFO_502_STR *sh502, prs_str if(!prs_align(ps)) return False; - if(!smb_io_unistr2("", &sh502->uni_netname, True, ps, depth)) - return False; + + if(sh502->ptrs->ptr_netname) { + if(!smb_io_unistr2("", &sh502->uni_netname, True, ps, depth)) + return False; + } if(!prs_align(ps)) return False; - if(!smb_io_unistr2("", &sh502->uni_remark, True, ps, depth)) - return False; + + if(sh502->ptrs->ptr_remark) { + if(!smb_io_unistr2("", &sh502->uni_remark, True, ps, depth)) + return False; + } if(!prs_align(ps)) return False; - if(!smb_io_unistr2("", &sh502->uni_path, True, ps, depth)) - return False; + + if(sh502->ptrs->ptr_path) { + if(!smb_io_unistr2("", &sh502->uni_path, True, ps, depth)) + return False; + } if(!prs_align(ps)) return False; - if(!smb_io_unistr2("", &sh502->uni_passwd, True, ps, depth)) - return False; + + if(sh502->ptrs->ptr_passwd) { + if(!smb_io_unistr2("", &sh502->uni_passwd, True, ps, depth)) + return False; + } if(!prs_align(ps)) return False; - if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size)) - return False; - if (!sec_io_desc(desc, &sh502->sd, ps, depth)) - return False; + if(sh502->ptrs->ptr_sd) { + if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size)) + return False; + if (!sec_io_desc(desc, &sh502->sd, ps, depth)) + return False; + } return True; } @@ -501,6 +523,7 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct } for (i = 0; i < num_entries; i++) { + info502[i].info_502_str.ptrs = &info502[i].info_502; if(!srv_io_share_info502_str("", &info502[i].info_502_str, ps, depth)) return False; } @@ -675,6 +698,9 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA if(!srv_io_share_info502("", &r_n->share.info502.info_502, ps, depth)) return False; + /*allow access to pointers in the str part. */ + r_n->share.info502.info_502_str.ptrs = &r_n->share.info502.info_502; + if(!srv_io_share_info502_str("", &r_n->share.info502.info_502_str, ps, depth)) return False; break; @@ -2232,6 +2258,57 @@ void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv, } /******************************************************************* + Inits a SRV_R_NET_SRV_SET_INFO structure. + ********************************************************************/ + +void init_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv, + uint32 switch_value, uint32 status) +{ + DEBUG(5,("init_srv_r_net_srv_set_info\n")); + + srv->switch_value = switch_value; + srv->status = status; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL srv_io_q_net_srv_set_info(char *desc, SRV_Q_NET_SRV_SET_INFO *q_n, + prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "srv_io_q_net_srv_set_info"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name)) + return False; + if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value)) + return False; + + if (UNMARSHALLING(ps)) { + q_n->ctr = (SRV_INFO_CTR *) + prs_alloc_mem(ps, sizeof(SRV_INFO_CTR)); + + if (!q_n->ctr) + return False; + } + + if(!srv_io_info_ctr("ctr", q_n->ctr, ps, depth)) + return False; + + return True; +} + +/******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -2255,6 +2332,27 @@ BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_stru return True; } +/******************************************************************* + Reads or writes a structure. + ********************************************************************/ + +BOOL srv_io_r_net_srv_set_info(char *desc, SRV_R_NET_SRV_SET_INFO *r_n, + prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "srv_io_r_net_srv_set_info"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("switch_value ", ps, depth, &r_n->switch_value)) + return False; + + if(!prs_uint32("status ", ps, depth, &r_n->status)) + return False; + + return True; +} /******************************************************************* Reads or writes a structure. @@ -2374,3 +2472,327 @@ BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct * return True; } + +/******************************************************************* + Reads or writes a structure. + ********************************************************************/ + +BOOL srv_io_q_net_disk_enum(char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps, int depth) +{ + if (q_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_q_net_disk_enum"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("level", ps, depth, &q_n->disk_enum_ctr.level)) + return False; + + if(!prs_uint32("entries_read", ps, depth, &q_n->disk_enum_ctr.entries_read)) + return False; + + if(!prs_uint32("buffer", ps, depth, &q_n->disk_enum_ctr.disk_info_ptr)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len)) + return False; + if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. + ********************************************************************/ + +BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth) +{ + int i; + + if (r_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_r_net_disk_enum"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("entries_read", ps, depth, &r_n->disk_enum_ctr.entries_read)) + return False; + if(!prs_uint32("ptr_disk_info", ps, depth, &r_n->disk_enum_ctr.disk_info_ptr)) + return False; + + /*this may be max, unknown, actual?*/ + + if(!prs_uint32("max_elements", ps, depth, &r_n->disk_enum_ctr.entries_read)) + return False; + if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.unknown)) + return False; + if(!prs_uint32("actual_elements", ps, depth, &r_n->disk_enum_ctr.entries_read)) + return False; + + for(i=0; i < r_n->disk_enum_ctr.entries_read; i++) { + + if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.disk_info[i].unknown)) + return False; + + if(!smb_io_unistr3("disk_name", &r_n->disk_enum_ctr.disk_info[i].disk_name, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + } + + if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries)) + return False; + + if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth)) + return False; + + if(!prs_uint32("status", ps, depth, &r_n->status)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. + ********************************************************************/ + +BOOL srv_io_q_net_name_validate(char *desc, SRV_Q_NET_NAME_VALIDATE *q_n, prs_struct *ps, int depth) +{ + if (q_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_q_net_name_validate"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("type", ps, depth, &q_n->type)) + return False; + + if(!prs_uint32("flags", ps, depth, &q_n->flags)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. + ********************************************************************/ + +BOOL srv_io_r_net_name_validate(char *desc, SRV_R_NET_NAME_VALIDATE *r_n, prs_struct *ps, int depth) +{ + if (r_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_r_net_name_validate"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("status", ps, depth, &r_n->status)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL srv_io_q_net_file_query_secdesc(char *desc, SRV_Q_NET_FILE_QUERY_SECDESC *q_n, prs_struct *ps, int depth) +{ + if (q_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_q_net_file_query_secdesc"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_qual_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_file_name, True, ps, depth)) + return False; + + if(!prs_uint32("unknown1", ps, depth, &q_n->unknown1)) + return False; + + if(!prs_uint32("unknown2", ps, depth, &q_n->unknown2)) + return False; + + if(!prs_uint32("unknown3", ps, depth, &q_n->unknown3)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL srv_io_r_net_file_query_secdesc(char *desc, SRV_R_NET_FILE_QUERY_SECDESC *r_n, prs_struct *ps, int depth) +{ + if (r_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_r_net_file_query_secdesc"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_response", ps, depth, &r_n->ptr_response)) + return False; + + if(!prs_uint32("size_response", ps, depth, &r_n->size_response)) + return False; + + if(!prs_uint32("ptr_secdesc", ps, depth, &r_n->ptr_secdesc)) + return False; + + if(!prs_uint32("size_secdesc", ps, depth, &r_n->size_secdesc)) + return False; + + if(!sec_io_desc("sec_desc", &r_n->sec_desc, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("status", ps, depth, &r_n->status)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL srv_io_q_net_file_set_secdesc(char *desc, SRV_Q_NET_FILE_SET_SECDESC *q_n, prs_struct *ps, int depth) +{ + if (q_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_q_net_file_set_secdesc"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_qual_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!smb_io_unistr2("", &q_n->uni_file_name, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("sec_info", ps, depth, &q_n->sec_info)) + return False; + + if(!prs_uint32("size_set", ps, depth, &q_n->size_set)) + return False; + + if(!prs_uint32("ptr_secdesc", ps, depth, &q_n->ptr_secdesc)) + return False; + + if(!prs_uint32("size_secdesc", ps, depth, &q_n->size_secdesc)) + return False; + + if(!sec_io_desc("sec_desc", &q_n->sec_desc, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +BOOL srv_io_r_net_file_set_secdesc(char *desc, SRV_R_NET_FILE_SET_SECDESC *r_n, prs_struct *ps, int depth) +{ + if (r_n == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_r_net_file_set_secdesc"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("status", ps, depth, &r_n->status)) + return False; + + return True; +} diff --git a/source/rpc_server/srv_dfs_nt.c b/source/rpc_server/srv_dfs_nt.c index c01ab8f2d9d..54c3fbf324c 100644 --- a/source/rpc_server/srv_dfs_nt.c +++ b/source/rpc_server/srv_dfs_nt.c @@ -121,7 +121,7 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u get_current_user(&user,p); if (user.uid != 0) { - DEBUG(10,("_dfs_add: uid != 0. Access denied.\n")); + DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n")); return ERROR_ACCESS_DENIED; } diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c index b6a8c745a45..005398924ee 100644 --- a/source/rpc_server/srv_lsa.c +++ b/source/rpc_server/srv_lsa.c @@ -269,6 +269,37 @@ static BOOL api_lsa_open_secret(pipes_struct *p) } /*************************************************************************** + api_lsa_UNK_GET_CONNUSER + ***************************************************************************/ + +static BOOL api_lsa_unk_get_connuser(pipes_struct *p) +{ + LSA_Q_UNK_GET_CONNUSER q_u; + LSA_R_UNK_GET_CONNUSER 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(!lsa_io_q_unk_get_connuser("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_unk_get_connuser: failed to unmarshall LSA_Q_UNK_GET_CONNUSER.\n")); + return False; + } + + r_u.status = _lsa_unk_get_connuser(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_unk_get_connuser("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_unk_get_connuser: Failed to marshall LSA_R_UNK_GET_CONNUSER.\n")); + return False; + } + + return True; +} + +/*************************************************************************** \PIPE\ntlsa commands ***************************************************************************/ @@ -282,6 +313,7 @@ static struct api_struct api_lsa_cmds[] = { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids }, { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names }, + { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser}, { NULL , 0 , NULL } }; diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c index 73626b038c9..afcace3f9c8 100644 --- a/source/rpc_server/srv_lsa_nt.c +++ b/source/rpc_server/srv_lsa_nt.c @@ -108,7 +108,7 @@ static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid) ***************************************************************************/ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, - int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS], + int num_entries, UNISTR2 *name, uint32 *mapped_count, BOOL endian) { int i; @@ -238,6 +238,11 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME sid_split_rid(&find_sid, &rid); } + /* unistr routines take dos codepage strings */ + + unix_to_dos(dom_name, True); + unix_to_dos(name, True); + dom_idx = init_dom_ref(ref, dom_name, &find_sid); DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to " @@ -332,6 +337,7 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO { LSA_INFO_UNION *info = &r_u->dom; DOM_SID domain_sid; + fstring dos_domain; char *name = NULL; DOM_SID *sid = NULL; @@ -340,6 +346,9 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO if (!find_policy_by_hnd(p, &q_u->pol, NULL)) return NT_STATUS_INVALID_HANDLE; + fstrcpy(dos_domain, global_myworkgroup); + unix_to_dos(dos_domain, True); + switch (q_u->info_class) { case 0x02: { @@ -355,24 +364,25 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO break; } case 0x03: - switch (lp_server_role()) - { + /* Request PolicyPrimaryDomainInformation. */ + switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - name = global_myworkgroup; + name = dos_domain; sid = &global_sam_sid; break; case ROLE_DOMAIN_MEMBER: - name = global_myname; - if (secrets_fetch_domain_sid(global_myworkgroup, - &domain_sid)) - sid = &domain_sid; + name = dos_domain; + /* We need to return the Domain SID here. */ + if (secrets_fetch_domain_sid(dos_domain, + &domain_sid)) + sid = &domain_sid; else - sid = &global_sam_sid; + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; break; case ROLE_STANDALONE: - name = global_myname; - sid = NULL; + name = dos_domain; + sid = NULL; /* Tell it we're not in a domain. */ break; default: return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; @@ -380,24 +390,19 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO init_dom_query(&r_u->dom.id3, name, sid); break; case 0x05: - /* AS/U shows this needs to be the same as level 3. JRA. */ - switch (lp_server_role()) - { + /* Request PolicyAccountDomainInformation. */ + switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - name = global_myworkgroup; + name = dos_domain; sid = &global_sam_sid; break; case ROLE_DOMAIN_MEMBER: - name = global_myname; - if (secrets_fetch_domain_sid(global_myworkgroup, - &domain_sid)) - sid = &domain_sid; - else - sid = &global_sam_sid; + name = dos_domain; + sid = &global_sam_sid; break; case ROLE_STANDALONE: - name = global_myname; + name = dos_domain; sid = &global_sam_sid; break; default: @@ -406,8 +411,7 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO init_dom_query(&r_u->dom.id5, name, sid); break; case 0x06: - switch (lp_server_role()) - { + switch (lp_server_role()) { case ROLE_DOMAIN_BDC: /* * only a BDC is a backup controller @@ -515,3 +519,33 @@ uint32 _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECR { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + +uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u) +{ + fstring username, domname; + int ulen, dlen; + user_struct *vuser = get_valid_user_struct(p->vuid); + + if (vuser == NULL) + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + + fstrcpy(username, vuser->user.smb_name); + fstrcpy(domname, vuser->user.domain); + + ulen = strlen(username); + dlen = strlen(domname); + + init_uni_hdr(&r_u->hdr_user_name, ulen); + r_u->ptr_user_name = 1; + init_unistr2(&r_u->uni2_user_name, username, ulen); + + r_u->unk1 = 1; + + init_uni_hdr(&r_u->hdr_dom_name, dlen); + r_u->ptr_dom_name = 1; + init_unistr2(&r_u->uni2_dom_name, domname, dlen); + + r_u->status = NT_STATUS_NO_PROBLEMO; + + return r_u->status; +} diff --git a/source/rpc_server/srv_netlog.c b/source/rpc_server/srv_netlog.c index 01d646bf576..4c13ad0c670 100644 --- a/source/rpc_server/srv_netlog.c +++ b/source/rpc_server/srv_netlog.c @@ -60,6 +60,37 @@ static BOOL api_net_req_chal(pipes_struct *p) } /************************************************************************* + api_net_auth: + *************************************************************************/ + +static BOOL api_net_auth(pipes_struct *p) +{ + NET_Q_AUTH q_u; + NET_R_AUTH r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the challenge... */ + if(!net_io_q_auth("", &q_u, data, 0)) { + DEBUG(0,("api_net_auth: Failed to unmarshall NET_Q_AUTH.\n")); + return False; + } + + r_u.status = _net_auth(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!net_io_r_auth("", &r_u, rdata, 0)) { + DEBUG(0,("api_net_auth: Failed to marshall NET_R_AUTH.\n")); + return False; + } + + return True; +} + +/************************************************************************* api_net_auth_2: *************************************************************************/ @@ -257,6 +288,7 @@ static BOOL api_net_logon_ctrl2(pipes_struct *p) static struct api_struct api_net_cmds [] = { { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal }, + { "NET_AUTH" , NET_AUTH , api_net_auth }, { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 }, { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset }, { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon }, diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c index d3d14901ecf..5a7505869c5 100644 --- a/source/rpc_server/srv_netlog_nt.c +++ b/source/rpc_server/srv_netlog_nt.c @@ -68,7 +68,7 @@ uint32 _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTR DEBUG(6,("_net_logon_ctrl2: %d\n", __LINE__)); /* set up the Logon Control2 response */ - init_r_logon_ctrl2(r_u, q_u->query_level, + init_net_r_logon_ctrl2(r_u, q_u->query_level, flags, pdc_connection_status, logon_attempts, tc_status, trusted_domain); @@ -96,18 +96,6 @@ uint32 _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRU return r_u->status; } -/************************************************************************* - init_net_r_auth_2: - *************************************************************************/ - -static void init_net_r_auth_2(NET_R_AUTH_2 *r_a, - DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status) -{ - memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); - memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs)); - r_a->status = status; -} - /*********************************************************************************** init_net_r_srv_pwset: ***********************************************************************************/ @@ -217,6 +205,62 @@ uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u) } /************************************************************************* + init_net_r_auth: + *************************************************************************/ + +static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, int status) +{ + memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); + r_a->status = status; +} + +/************************************************************************* + _net_auth + *************************************************************************/ + +uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u) +{ + uint32 status = NT_STATUS_NOPROBLEMO; + DOM_CHAL srv_cred; + UTIME srv_time; + + if (!get_valid_user_struct(p->vuid)) + return NT_STATUS_NO_SUCH_USER; + + srv_time.time = 0; + + /* check that the client credentials are valid */ + if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) { + + /* create server challenge for inclusion in the reply */ + cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred); + + /* copy the received client credentials for use next time */ + memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data)); + memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data)); + } else { + status = NT_STATUS_ACCESS_DENIED; + } + + /* set up the LSA AUTH 2 response */ + init_net_r_auth(r_u, &srv_cred, status); + + return r_u->status; +} + +/************************************************************************* + init_net_r_auth_2: + *************************************************************************/ + +static void init_net_r_auth_2(NET_R_AUTH_2 *r_a, + DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status) +{ + memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); + memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs)); + r_a->status = status; +} + +/************************************************************************* _net_auth_2 *************************************************************************/ @@ -382,8 +426,8 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_p dump_data(100, nt_pwd, 16); #endif - SamOEMhash((uchar *)lm_pwd, key, False); - SamOEMhash((uchar *)nt_pwd, key, False); + SamOEMhash((uchar *)lm_pwd, key, 16); + SamOEMhash((uchar *)nt_pwd, key, 16); #ifdef DEBUG_PASSWORD DEBUG(100,("decrypt of lm owf password:")); @@ -456,26 +500,26 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass) uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u) { uint32 status = NT_STATUS_NOPROBLEMO; - NET_USER_INFO_3 *usr_info = NULL; - DOM_CRED srv_cred; - struct smb_passwd *smb_pass = NULL; - struct sam_passwd *sam_pass = NULL; - UNISTR2 *uni_samlogon_user = NULL; - fstring nt_username; + NET_USER_INFO_3 *usr_info = NULL; + DOM_CRED srv_cred; + struct smb_passwd *smb_pass = NULL; + struct sam_passwd *sam_pass = NULL; + UNISTR2 *uni_samlogon_user = NULL; + fstring nt_username; usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3)); if (!usr_info) return NT_STATUS_NO_MEMORY; ZERO_STRUCTP(usr_info); - if (!get_valid_user_struct(p->vuid)) - return NT_STATUS_NO_SUCH_USER; + if (!get_valid_user_struct(p->vuid)) + return NT_STATUS_NO_SUCH_USER; - /* checks and updates credentials. creates reply credentials */ - if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)) - return NT_STATUS_INVALID_HANDLE; - else - memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred)); + /* checks and updates credentials. creates reply credentials */ + if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)) + return NT_STATUS_INVALID_HANDLE; + else + memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred)); r_u->buffer_creds = 1; /* yes, we have valid server credentials */ memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds)); @@ -486,7 +530,7 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_ r_u->auth_resp = 1; /* authoritative response */ r_u->switch_value = 3; /* indicates type of validation user info */ - /* find the username */ + /* find the username */ switch (q_u->sam_id.logon_level) { case INTERACTIVE_LOGON_TYPE: @@ -550,9 +594,15 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_ } #ifdef WITH_PAM - if (!pam_accountcheck(nt_username)) { - return NT_STATUS_ACCOUNT_DISABLED; - } + become_root(); +#if 0 /* JERRY */ + status = smb_pam_accountcheck(nt_username); +#else + status = smb_pam_accountcheck(sam_pass->smb_name); +#endif + unbecome_root(); + if (status != NT_STATUS_NOPROBLEMO) + return status; #endif if (!(smb_pass->acct_ctrl & ACB_PWNOTREQ)) { diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c index 07e4e73142e..d16290985ec 100644 --- a/source/rpc_server/srv_pipe.c +++ b/source/rpc_server/srv_pipe.c @@ -93,7 +93,7 @@ BOOL create_next_pdu(pipes_struct *p) */ if(p->fault_state) { - setup_fault_pdu(p); + setup_fault_pdu(p, 0x1c010002); return True; } @@ -626,7 +626,7 @@ static BOOL setup_bind_nak(pipes_struct *p) Marshall a fault pdu. *******************************************************************/ -BOOL setup_fault_pdu(pipes_struct *p) +BOOL setup_fault_pdu(pipes_struct *p, uint32 status) { prs_struct outgoing_pdu; RPC_HDR fault_hdr; @@ -658,7 +658,7 @@ BOOL setup_fault_pdu(pipes_struct *p) memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); - fault_resp.status = 0x1c010002; + fault_resp.status = status; fault_resp.reserved = 0; /* @@ -1204,7 +1204,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, * and not put the pipe into fault state. JRA. */ DEBUG(4, ("unknown\n")); - setup_fault_pdu(p); + setup_fault_pdu(p, 0x1c010002); return True; } diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c index 893bc8cb884..f91df7c4ef4 100644 --- a/source/rpc_server/srv_pipe_hnd.c +++ b/source/rpc_server/srv_pipe_hnd.c @@ -570,7 +570,7 @@ static ssize_t process_complete_pdu(pipes_struct *p) DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n", p->name )); set_incoming_fault(p); - setup_fault_pdu(p); + setup_fault_pdu(p, 0x1c010002); return (ssize_t)data_len; } @@ -619,7 +619,7 @@ static ssize_t process_complete_pdu(pipes_struct *p) if (!reply) { DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on pipe %s\n", p->pipe_srv_name)); set_incoming_fault(p); - setup_fault_pdu(p); + setup_fault_pdu(p, 0x1c010002); prs_mem_free(&rpc_in); } else { /* diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c index 63150573139..cd1cc6926fc 100644 --- a/source/rpc_server/srv_samr.c +++ b/source/rpc_server/srv_samr.c @@ -670,6 +670,11 @@ static BOOL api_samr_set_userinfo(pipes_struct *p) if (!samr_io_q_set_userinfo("", &q_u, data, 0)) { DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n")); + /* Fix for W2K SP2 */ + if (q_u.switch_value == 0x1a) { + setup_fault_pdu(p, 0x1c000006); + return True; + } return False; } diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c index 929a14afeb3..bccff04e308 100644 --- a/source/rpc_server/srv_samr_nt.c +++ b/source/rpc_server/srv_samr_nt.c @@ -61,7 +61,7 @@ static void free_samr_info(void *ptr) dynamically returns the correct user info..... JRA. ********************************************************************/ -static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, +static uint32 get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, int *total_entries, int *num_entries, int max_num_entries, uint16 acb_mask) { @@ -72,12 +72,12 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, (*total_entries) = 0; if (pw_buf == NULL) - return False; + return NT_STATUS_NO_MEMORY; vp = startsmbpwent(False); if (!vp) { DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) { @@ -119,10 +119,13 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, endsmbpwent(vp); - return (*num_entries) > 0; + if (pwd!=NULL) + return STATUS_MORE_ENTRIES; + else + return NT_STATUS_NO_PROBLEMO; } -static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, +static uint32 jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, int *total_entries, uint32 *num_entries, int max_num_entries, uint16 acb_mask) { @@ -133,12 +136,12 @@ static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, *total_entries = 0; if (pw_buf == NULL) - return False; + return NT_STATUS_NO_MEMORY; vp = startsmbpwent(False); if (!vp) { DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) { @@ -183,7 +186,11 @@ static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, endsmbpwent(vp); *total_entries = *num_entries; - return True; + + if (pwd!=NULL) + return STATUS_MORE_ENTRIES; + else + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -675,7 +682,6 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]; int num_entries = 0; int total_entries = 0; - BOOL ret; r_u->status = NT_STATUS_NOPROBLEMO; @@ -686,12 +692,12 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); become_root(); - ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask); unbecome_root(); - if (!ret) - return NT_STATUS_ACCESS_DENIED; + if (r_u->status != NT_STATUS_NOPROBLEMO && r_u->status != STATUS_MORE_ENTRIES) + return r_u->status; samr_clear_passwd_fields(pass, num_entries); @@ -775,34 +781,41 @@ static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 star /* well-known aliases */ if (strequal(sid_str, "S-1-5-32")) { - char *name; + char *alias_name; while (!lp_hide_local_users() && num_entries < max_entries && - ((name = builtin_alias_rids[num_entries].name) != NULL)) { + ((alias_name = builtin_alias_rids[num_entries].name) != NULL)) { - fstrcpy(d_grp[num_entries].name, name); + fstrcpy(d_grp[num_entries].name, alias_name); d_grp[num_entries].rid = builtin_alias_rids[num_entries].rid; num_entries++; } } else if (strequal(sid_str, sam_sid_str) && !lp_hide_local_users()) { - char *name; + fstring name; char *sep; - struct group *grp; + struct sys_grent *glist; + struct sys_grent *grp; sep = lp_winbind_separator(); /* local aliases */ /* we return the UNIX groups here. This seems to be the right */ /* thing to do, since NT member servers return their local */ - /* groups in the same situation. */ - setgrent(); + /* groups in the same situation. */ + + /* use getgrent_list() to retrieve the list of groups to avoid + * problems with getgrent possible infinite loop by internal + * libc grent structures overwrites by called functions */ + grp = glist = getgrent_list(); + if (grp == NULL) + return False; - while (num_entries < max_entries && ((grp = getgrent()) != NULL)) { + for (;(num_entries < max_entries) && (grp != NULL); grp = grp->next) { int i; uint32 trid; - name = grp->gr_name; + fstrcpy(name,grp->gr_name); DEBUG(10,("get_group_alias_entries: got group %s\n", name )); /* Don't return winbind groups as they are not local! */ @@ -820,7 +833,8 @@ static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 star trid = pdb_gid_to_group_rid(grp->gr_gid); for( i = 0; i < num_entries; i++) - if ( d_grp[i].rid == trid ) break; + if ( d_grp[i].rid == trid ) + break; if ( i < num_entries ) continue; /* rid was there, dup! */ @@ -840,7 +854,7 @@ static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 star num_entries++; } - endgrent(); + grent_free(glist); } *p_num_entries = num_entries; @@ -852,7 +866,7 @@ static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 star Get the group entries - similar to get_sampwd_entries(). ********************************************************************/ -static BOOL get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx, +static uint32 get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx, uint32 *p_num_entries, uint32 max_entries) { fstring sid_str; @@ -880,7 +894,7 @@ static BOOL get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 sta *p_num_entries = num_entries; - return True; + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -959,7 +973,7 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ int total_entries = 0; uint32 data_size = 0; DOM_SID sid; - BOOL ret; + uint32 disp_ret; SAM_DISPINFO_CTR *ctr; DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__)); @@ -984,30 +998,30 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ case 0x4: become_root(); #if 0 - ret = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, acb_mask); #endif #if 0 /* * Which should we use here ? JRA. */ - ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, acb_mask); #endif #if 1 - ret = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, acb_mask); #endif unbecome_root(); - if (!ret) { + if (r_u->status!=STATUS_MORE_ENTRIES && r_u->status!=NT_STATUS_NO_PROBLEMO) { DEBUG(5, ("get_sampwd_entries: failed\n")); - return NT_STATUS_ACCESS_DENIED; + return r_u->status; } break; case 0x3: case 0x5: - ret = get_group_domain_entries(grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES); - if (!ret) + r_u->status = get_group_domain_entries(grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES); + if (r_u->status!=NT_STATUS_NO_PROBLEMO) return NT_STATUS_ACCESS_DENIED; break; default: @@ -1015,6 +1029,7 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ return NT_STATUS_INVALID_INFO_CLASS; } + orig_num_entries = num_entries; if (num_entries > q_u->max_entries) num_entries = q_u->max_entries; @@ -1028,31 +1043,47 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ samr_clear_passwd_fields(pass, num_entries); data_size = q_u->max_size; - orig_num_entries = num_entries; ctr = (SAM_DISPINFO_CTR *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_CTR)); + if (!ctr) + return NT_STATUS_NO_MEMORY; /* Now create reply structure */ switch (q_u->switch_level) { case 0x1: - ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1)); - init_sam_dispinfo_1(ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass); + if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1)))) + return NT_STATUS_NO_MEMORY; + disp_ret = init_sam_dispinfo_1(p->mem_ctx,ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x2: - ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2)); - init_sam_dispinfo_2(ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass); + if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2)))) + return NT_STATUS_NO_MEMORY; + disp_ret = init_sam_dispinfo_2(p->mem_ctx,ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x3: - ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3)); - init_sam_dispinfo_3(ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps); + if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3)))) + return NT_STATUS_NO_MEMORY; + disp_ret = init_sam_dispinfo_3(p->mem_ctx,ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x4: - ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4)); - init_sam_dispinfo_4(ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass); + if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4)))) + return NT_STATUS_NO_MEMORY; + disp_ret = init_sam_dispinfo_4(p->mem_ctx,ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x5: - ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5)); - init_sam_dispinfo_5(ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps); + if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5)))) + return NT_STATUS_NO_MEMORY; + disp_ret = init_sam_dispinfo_5(p->mem_ctx,ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; default: ctr->sam.info = NULL; @@ -1061,11 +1092,10 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__)); - init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status); + if (num_entries < orig_num_entries) + r_u->status = STATUS_MORE_ENTRIES; - if (num_entries < orig_num_entries) { - return STATUS_MORE_ENTRIES; - } + init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status); return r_u->status; } @@ -1181,7 +1211,7 @@ uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOK uint32 rid[MAX_SAM_ENTRIES]; enum SID_NAME_USE type[MAX_SAM_ENTRIES]; int i; - int num_rids = q_u->num_names1; + int num_rids = q_u->num_names2; DOM_SID pol_sid; r_u->status = NT_STATUS_NOPROBLEMO; @@ -1201,8 +1231,6 @@ uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOK DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids)); } - SMB_ASSERT_ARRAY(q_u->uni_name, num_rids); - for (i = 0; i < num_rids; i++) { fstring name; @@ -1756,7 +1784,7 @@ uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u) { - struct sam_passwd *sam_pass; + struct sam_passwd *sam_pass = NULL; fstring mach_acct; pstring err_str; pstring msg_str; @@ -1821,7 +1849,6 @@ uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CR sizeof(err_str), msg_str, sizeof(msg_str))) { DEBUG(0, ("%s\n", err_str)); - close_policy_hnd(p, user_pol); return NT_STATUS_ACCESS_DENIED; } @@ -1830,19 +1857,16 @@ uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CR unbecome_root(); if (sam_pass == NULL) { /* account doesn't exist: say so */ - close_policy_hnd(p, user_pol); return NT_STATUS_ACCESS_DENIED; } /* Get the domain SID stored in the domain policy */ if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) { - close_policy_hnd(p, user_pol); return NT_STATUS_INVALID_HANDLE; } /* append the user's RID to it */ if(!sid_append_rid(&sid, sam_pass->user_rid)) { - close_policy_hnd(p, user_pol); return NT_STATUS_NO_SUCH_USER; } @@ -2198,10 +2222,10 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid) } /******************************************************************* - set_user_info_24 + set_user_info_pw ********************************************************************/ -static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid) +static BOOL set_user_info_pw(char *pass, uint32 rid) { struct sam_passwd *pwd = getsam21pwrid(rid); struct sam_passwd new_pwd; @@ -2218,7 +2242,7 @@ static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid) memset(buf, 0, sizeof(pstring)); - if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len, nt_hash, lm_hash)) + if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) return False; new_pwd.smb_passwd = lm_hash; @@ -2239,7 +2263,7 @@ static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid) memset(buf, 0, sizeof(buf)); - DEBUG(5,("set_user_info_24: pdb_update_sam_account()\n")); + DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n")); /* update the SAMBA password */ if(!mod_sam21pwd_entry(&new_pwd, True)) @@ -2313,13 +2337,39 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_ break; case 24: - SamOEMhash(ctr->info.id24->pass, sess_key, 1); - if (!set_user_info_24(ctr->info.id24, rid)) + SamOEMhash(ctr->info.id24->pass, sess_key, 516); + + dump_data(100, (char *)ctr->info.id24->pass, 516); + + if (!set_user_info_pw((char *)(ctr->info.id24->pass), rid)) + return NT_STATUS_ACCESS_DENIED; + break; + + case 25: +#if 0 + /* + * Currently we don't really know how to unmarshall + * the level 25 struct, and the password encryption + * is different. This is a placeholder for when we + * do understand it. In the meantime just return INVALID + * info level and W2K SP2 drops down to level 23... JRA. + */ + + SamOEMhash(ctr->info.id25->pass, sess_key, 532); + + dump_data(100, (char *)ctr->info.id25->pass, 532); + + if (!set_user_info_pw(ctr->info.id25->pass, rid)) return NT_STATUS_ACCESS_DENIED; break; +#endif + return NT_STATUS_INVALID_INFO_CLASS; case 23: - SamOEMhash(ctr->info.id23->pass, sess_key, 1); + SamOEMhash(ctr->info.id23->pass, sess_key, 516); + + dump_data(100, (char *)ctr->info.id23->pass, 516); + if (!set_user_info_23(ctr->info.id23, rid)) return NT_STATUS_ACCESS_DENIED; break; diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c index ddd8255139a..63bbc5f87b7 100755 --- a/source/rpc_server/srv_spoolss.c +++ b/source/rpc_server/srv_spoolss.c @@ -214,6 +214,38 @@ static BOOL api_spoolss_deleteprinter(pipes_struct *p) /******************************************************************** + * api_spoolss_deleteprinterdriver + * + * called from the spoolss dispatcher + ********************************************************************/ + +static BOOL api_spoolss_deleteprinterdriver(pipes_struct *p) +{ + SPOOL_Q_DELETEPRINTERDRIVER q_u; + SPOOL_R_DELETEPRINTERDRIVER 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 (!spoolss_io_q_deleteprinterdriver("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_deleteprinterdriver: unable to unmarshall SPOOL_Q_DELETEPRINTERDRIVER.\n")); + return False; + } + + r_u.status = _spoolss_deleteprinterdriver(p, &q_u, &r_u); + + if (!spoolss_io_r_deleteprinterdriver("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_deleteprinter: unable to marshall SPOOL_R_DELETEPRINTER.\n")); + return False; + } + + return True; +} + + +/******************************************************************** * api_spoolss_rffpcnex * ReplyFindFirstPrinterChangeNotifyEx ********************************************************************/ @@ -1059,6 +1091,38 @@ static BOOL api_spoolss_enumprintprocessors(pipes_struct *p) /**************************************************************************** ****************************************************************************/ +static BOOL api_spoolss_addprintprocessor(pipes_struct *p) +{ + SPOOL_Q_ADDPRINTPROCESSOR q_u; + SPOOL_R_ADDPRINTPROCESSOR 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(!spoolss_io_q_addprintprocessor("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addprintprocessor: unable to unmarshall SPOOL_Q_ADDPRINTPROCESSOR.\n")); + return False; + } + + /* for now, just indicate success and ignore the add. We'll + automatically set the winprint processor for printer + entries later. Used to debug the LexMark Optra S 1855 PCL + driver --jerry */ + r_u.status = NT_STATUS_NO_PROBLEMO; + + if(!spoolss_io_r_addprintprocessor("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_addprintprocessor: unable to marshall SPOOL_R_ADDPRINTPROCESSOR.\n")); + return False; + } + + return True; +} + +/**************************************************************************** +****************************************************************************/ + static BOOL api_spoolss_enumprintprocdatatypes(pipes_struct *p) { SPOOL_Q_ENUMPRINTPROCDATATYPES q_u; @@ -1169,6 +1233,7 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_ENUMPRINTERDRIVERS", SPOOLSS_ENUMPRINTERDRIVERS, api_spoolss_enumprinterdrivers }, {"SPOOLSS_ADDPRINTEREX", SPOOLSS_ADDPRINTEREX, api_spoolss_addprinterex }, {"SPOOLSS_ADDPRINTERDRIVER", SPOOLSS_ADDPRINTERDRIVER, api_spoolss_addprinterdriver }, + {"SPOOLSS_DELETEPRINTERDRIVER", SPOOLSS_DELETEPRINTERDRIVER, api_spoolss_deleteprinterdriver }, {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory }, {"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata }, {"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata }, @@ -1177,6 +1242,7 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_DELETEFORM", SPOOLSS_DELETEFORM, api_spoolss_deleteform }, {"SPOOLSS_GETFORM", SPOOLSS_GETFORM, api_spoolss_getform }, {"SPOOLSS_SETFORM", SPOOLSS_SETFORM, api_spoolss_setform }, + {"SPOOLSS_ADDPRINTPROCESSOR", SPOOLSS_ADDPRINTPROCESSOR, api_spoolss_addprintprocessor }, {"SPOOLSS_ENUMPRINTPROCESSORS", SPOOLSS_ENUMPRINTPROCESSORS, api_spoolss_enumprintprocessors }, {"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors }, {"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob }, diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index aa943996307..3fcb08891df 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -34,6 +34,13 @@ extern pstring global_myname; #define PRINTER_HANDLE_IS_PRINTER 0 #define PRINTER_HANDLE_IS_PRINTSERVER 1 +struct table_node { + char *long_archi; + char *short_archi; + int version; +}; + + /* structure to store the printer handles */ /* and a reference to what it's pointing to */ /* and the notify info asked about */ @@ -371,7 +378,7 @@ static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename } /* it's a print server */ - if (!strchr(handlename+2, '\\')) { + if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr(handlename+2, '\\')) { DEBUGADD(4,("Printer is a print server\n")); Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER; } @@ -407,8 +414,13 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER) return False; - aprinter=strchr(handlename+2, '\\'); - aprinter++; + if (*handlename=='\\') { + aprinter=strchr(handlename+2, '\\'); + aprinter++; + } + else { + aprinter=handlename; + } DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter))); @@ -600,7 +612,7 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) receive the notify message ****************************************************************************/ -void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len) +static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len) { fstring printer; uint32 status; @@ -1053,6 +1065,81 @@ uint32 _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL return result; } +/******************************************************************* + * static function to lookup the version id corresponding to an + * long architecture string + ******************************************************************/ +static int get_version_id (char * arch) +{ + int i; + struct table_node archi_table[]= { + + {"Windows 4.0", "WIN40", 0 }, + {"Windows NT x86", "W32X86", 2 }, + {"Windows NT R4000", "W32MIPS", 2 }, + {"Windows NT Alpha_AXP", "W32ALPHA", 2 }, + {"Windows NT PowerPC", "W32PPC", 2 }, + {NULL, "", -1 } + }; + + for (i=0; archi_table[i].long_archi != NULL; i++) + { + if (strcmp(arch, archi_table[i].long_archi) == 0) + return (archi_table[i].version); + } + + return -1; +} + +/******************************************************************** + * _spoolss_deleteprinterdriver + * + * We currently delete the driver for the architecture only. + * This can leave the driver for other archtectures. However, + * since every printer associates a "Windows NT x86" driver name + * and we cannot delete that one while it is in use, **and** since + * it is impossible to assign a driver to a Samba printer without + * having the "Windows NT x86" driver installed,... + * + * ....we should not get into trouble here. + * + * --jerry + ********************************************************************/ + +uint32 _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, + SPOOL_R_DELETEPRINTERDRIVER *r_u) +{ + fstring driver; + fstring arch; + NT_PRINTER_DRIVER_INFO_LEVEL info; + int version; + + unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); + unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); + + /* check that we have a valid driver name first */ + if ((version=get_version_id(arch)) == -1) { + /* this is what NT returns */ + return ERROR_INVALID_ENVIRONMENT; + } + + ZERO_STRUCT(info); + if (get_a_printer_driver (&info, 3, driver, arch, version) != 0) { + /* this is what NT returns */ + return ERROR_UNKNOWN_PRINTER_DRIVER; + } + + + if (printer_driver_in_use(arch, driver)) + { + /* this is what NT returns */ + return ERROR_PRINTER_DRIVER_IN_USE; + } + + return delete_printer_driver(info.info_3); +} + + /******************************************************************** GetPrinterData on a printer server Handle. ********************************************************************/ @@ -1266,7 +1353,12 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin * and connect to the IPC$ share anonumously */ if (smb_connections==0) { - if(!spoolss_connect_to_client(&cli, printer+2)) /* the +2 is to strip the leading 2 backslashs */ + fstring unix_printer; + + fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */ + dos_to_unix(unix_printer, True); + + if(!spoolss_connect_to_client(&cli, unix_printer)) return False; message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message); @@ -4029,35 +4121,35 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level, nt_printing_getsec(p->mem_ctx, Printer->dev.handlename, &old_secdesc_ctr); if (DEBUGLEVEL >= 10) { - SEC_ACL *acl; + SEC_ACL *the_acl; int i; - acl = old_secdesc_ctr->sec->dacl; + the_acl = old_secdesc_ctr->sec->dacl; DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n", - PRINTERNAME(snum), acl->num_aces)); + PRINTERNAME(snum), the_acl->num_aces)); - for (i = 0; i < acl->num_aces; i++) { + for (i = 0; i < the_acl->num_aces; i++) { fstring sid_str; - sid_to_string(sid_str, &acl->ace[i].sid); + sid_to_string(sid_str, &the_acl->ace[i].sid); DEBUG(10, ("%s 0x%08x\n", sid_str, - acl->ace[i].info.mask)); + the_acl->ace[i].info.mask)); } - acl = secdesc_ctr->sec->dacl; + the_acl = secdesc_ctr->sec->dacl; - if (acl) { + if (the_acl) { DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", - PRINTERNAME(snum), acl->num_aces)); + PRINTERNAME(snum), the_acl->num_aces)); - for (i = 0; i < acl->num_aces; i++) { + for (i = 0; i < the_acl->num_aces; i++) { fstring sid_str; - sid_to_string(sid_str, &acl->ace[i].sid); + sid_to_string(sid_str, &the_acl->ace[i].sid); DEBUG(10, ("%s 0x%08x\n", sid_str, - acl->ace[i].info.mask)); + the_acl->ace[i].info.mask)); } } else { DEBUG(10, ("dacl for secdesc_ctr is NULL\n")); @@ -4121,7 +4213,6 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer) { char *cmd = lp_addprinter_cmd(); - char *path; char **qlines; pstring command; pstring driverlocation; @@ -4129,11 +4220,6 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer) int ret; int fd; - if (*lp_pathname(lp_servicenumber(PRINTERS_NAME))) - path = lp_pathname(lp_servicenumber(PRINTERS_NAME)); - else - path = lp_lockdir(); - /* build driver path... only 9X architecture is needed for legacy reasons */ slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0", global_myname); @@ -5305,7 +5391,7 @@ uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM * FORM_1 form_1; fstring form_name; int buffer_size=0; - int numofforms=0, i = -1; + int numofforms=0, i=0; /* that's an [in out] buffer */ spoolss_move_buffer(q_u->buffer, &r_u->buffer); @@ -5402,18 +5488,12 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need if (*lp_enumports_cmd()) { char *cmd = lp_enumports_cmd(); - char *path; char **qlines; pstring command; int numlines; int ret; int fd; - if (*lp_pathname(lp_servicenumber(PRINTERS_NAME))) - path = lp_pathname(lp_servicenumber(PRINTERS_NAME)); - else - path = lp_lockdir(); - slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1); DEBUG(10,("Running [%s]\n", command)); @@ -5510,7 +5590,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need else path = lp_lockdir(); - slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%d.", path, sys_getpid()); + slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%u.", path, (unsigned int)sys_getpid()); slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 2); unlink(tmp_file); diff --git a/source/rpc_server/srv_srvsvc.c b/source/rpc_server/srv_srvsvc.c index d4d5e1bfe86..fe008d0dde8 100644 --- a/source/rpc_server/srv_srvsvc.c +++ b/source/rpc_server/srv_srvsvc.c @@ -56,6 +56,33 @@ static BOOL api_srv_net_srv_get_info(pipes_struct *p) } /******************************************************************* + api_srv_net_srv_get_info +********************************************************************/ + +static BOOL api_srv_net_srv_set_info(pipes_struct *p) +{ + SRV_Q_NET_SRV_SET_INFO q_u; + SRV_R_NET_SRV_SET_INFO r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the net server set info */ + if (!srv_io_q_net_srv_set_info("", &q_u, data, 0)) + return False; + + r_u.status = _srv_net_srv_set_info(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if (!srv_io_r_net_srv_set_info("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* api_srv_net_file_enum ********************************************************************/ @@ -345,6 +372,126 @@ static BOOL api_srv_net_remote_tod(pipes_struct *p) } /******************************************************************* + RPC to enumerate disks available on a server e.g. C:, D: ... +*******************************************************************/ + +static BOOL api_srv_net_disk_enum(pipes_struct *p) +{ + SRV_Q_NET_DISK_ENUM q_u; + SRV_R_NET_DISK_ENUM r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* Unmarshall the net server disk enum. */ + if(!srv_io_q_net_disk_enum("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_disk_enum: Failed to unmarshall SRV_Q_NET_DISK_ENUM.\n")); + return False; + } + + r_u.status = _srv_net_disk_enum(p, &q_u, &r_u); + + if(!srv_io_r_net_disk_enum("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_disk_enum: Failed to marshall SRV_R_NET_DISK_ENUM.\n")); + return False; + } + + return True; +} + +/******************************************************************* + NetValidateName (opnum 0x21) +*******************************************************************/ + +static BOOL api_srv_net_name_validate(pipes_struct *p) +{ + SRV_Q_NET_NAME_VALIDATE q_u; + SRV_R_NET_NAME_VALIDATE r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* Unmarshall the net server disk enum. */ + if(!srv_io_q_net_name_validate("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_name_validate: Failed to unmarshall SRV_Q_NET_NAME_VALIDATE.\n")); + return False; + } + + r_u.status = _srv_net_name_validate(p, &q_u, &r_u); + + if(!srv_io_r_net_name_validate("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_name_validate: Failed to marshall SRV_R_NET_NAME_VALIDATE.\n")); + return False; + } + + return True; +} + +/******************************************************************* + NetFileQuerySecdesc (opnum 0x27) +*******************************************************************/ + +static BOOL api_srv_net_file_query_secdesc(pipes_struct *p) +{ + SRV_Q_NET_FILE_QUERY_SECDESC q_u; + SRV_R_NET_FILE_QUERY_SECDESC r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* Unmarshall the net file get info from Win9x */ + if(!srv_io_q_net_file_query_secdesc("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_file_query_secdesc: Failed to unmarshall SRV_Q_NET_FILE_QUERY_SECDESC.\n")); + return False; + } + + r_u.status = _srv_net_file_query_secdesc(p, &q_u, &r_u); + + if(!srv_io_r_net_file_query_secdesc("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_file_query_secdesc: Failed to marshall SRV_R_NET_FILE_QUERY_SECDESC.\n")); + return False; + } + + return True; +} + +/******************************************************************* + NetFileSetSecdesc (opnum 0x28) +*******************************************************************/ + +static BOOL api_srv_net_file_set_secdesc(pipes_struct *p) +{ + SRV_Q_NET_FILE_SET_SECDESC q_u; + SRV_R_NET_FILE_SET_SECDESC r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* Unmarshall the net file set info from Win9x */ + if(!srv_io_q_net_file_set_secdesc("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_file_set_secdesc: Failed to unmarshall SRV_Q_NET_FILE_SET_SECDESC.\n")); + return False; + } + + r_u.status = _srv_net_file_set_secdesc(p, &q_u, &r_u); + + if(!srv_io_r_net_file_set_secdesc("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_file_set_secdesc: Failed to marshall SRV_R_NET_FILE_SET_SECDESC.\n")); + return False; + } + + return True; +} + +/******************************************************************* \PIPE\srvsvc commands ********************************************************************/ @@ -360,7 +507,12 @@ struct api_struct api_srv_cmds[] = { "SRV_NET_SHARE_SET_INFO", SRV_NET_SHARE_SET_INFO, api_srv_net_share_set_info }, { "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum }, { "SRV_NET_SRV_GET_INFO" , SRV_NET_SRV_GET_INFO , api_srv_net_srv_get_info }, + { "SRV_NET_SRV_SET_INFO" , SRV_NET_SRV_SET_INFO , api_srv_net_srv_set_info }, { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod }, + { "SRV_NET_DISK_ENUM" , SRV_NET_DISK_ENUM , api_srv_net_disk_enum }, + { "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate}, + { "SRV_NETFILEQUERYSECDESC",SRV_NETFILEQUERYSECDESC,api_srv_net_file_query_secdesc}, + { "SRV_NETFILESETSECDESC" , SRV_NETFILESETSECDESC , api_srv_net_file_set_secdesc}, { NULL , 0 , NULL } }; diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index 887c100d577..b487eb1c824 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -77,6 +77,14 @@ static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum) pstring_sub(remark,"%S",lp_servicename(snum)); pstrcpy(path, "C:"); pstrcat(path, lp_pathname(snum)); + + /* + * Change / to \\ so that win2k will see it as a valid path. This was added to + * enable use of browsing in win2k add share dialog. + */ + + string_replace(path, '/', '\\'); + pstrcpy(passwd, ""); len_net_name = strlen(net_name); @@ -117,7 +125,7 @@ BOOL share_info_db_init(void) char *vstring = "INFO/version"; if (share_tdb && local_pid == sys_getpid()) return True; - share_tdb = tdb_open(lock_path("share_info.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); + share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, 0, O_RDWR|O_CREAT, 0600); if (!share_tdb) { DEBUG(0,("Failed to open share info database %s (%s)\n", lock_path("share_info.tdb"), strerror(errno) )); @@ -363,6 +371,14 @@ static void init_srv_share_info_502(TALLOC_CTX *ctx, SRV_SHARE_INFO_502 *sh502, pstring_sub(remark,"%S",lp_servicename(snum)); pstrcpy(path, "C:"); pstrcat(path, lp_pathname(snum)); + + /* + * Change / to \\ so that win2k will see it as a valid path. This was added to + * enable use of browsing in win2k add share dialog. + */ + + string_replace(path, '/', '\\'); + pstrcpy(passwd, ""); len_net_name = strlen(net_name); @@ -379,7 +395,7 @@ static void init_srv_share_info_502(TALLOC_CTX *ctx, SRV_SHARE_INFO_502 *sh502, sd = get_share_security(ctx, snum, &sd_size); init_srv_share_info502(&sh502->info_502, net_name, type, remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size); - init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size); + init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size); } /*************************************************************************** @@ -1032,6 +1048,28 @@ uint32 _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R } /******************************************************************* +net server set info +********************************************************************/ + +uint32 _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u) +{ + /* NT gives "Windows NT error 0xc00000022" if we return + NT_STATUS_ACCESS_DENIED here so just pretend everything is OK. */ + + uint32 status = NT_STATUS_NOPROBLEMO; + + DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + + /* Set up the net server set info structure. */ + + init_srv_r_net_srv_set_info(r_u, 0x0, status); + + DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + + return r_u->status; +} + +/******************************************************************* net file enum ********************************************************************/ @@ -1546,3 +1584,293 @@ uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET return r_u->status; } + +/*********************************************************************************** + Win9x NT tools get security descriptor. +***********************************************************************************/ + +uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u, + SRV_R_NET_FILE_QUERY_SECDESC *r_u) +{ + SEC_DESC *psd = NULL; + size_t sd_size; + fstring null_pw; + pstring filename; + pstring qualname; + files_struct *fsp = NULL; + SMB_STRUCT_STAT st; + BOOL bad_path; + int access_mode; + int action; + int ecode; + struct current_user user; + fstring user_name; + connection_struct *conn = NULL; + + ZERO_STRUCT(st); + + r_u->status = NT_STATUS_NOPROBLEMO; + + unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname)); + + /* Null password is ok - we are already an authenticated user... */ + *null_pw = '\0'; + + get_current_user(&user, p); + fstrcpy(user_name, uidtoname(user.uid)); + + conn = make_connection(qualname, user_name, null_pw, 0, "A:", user.vuid, &ecode); + + if (conn == NULL) { + DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname)); + r_u->status = (uint32)ecode; + goto error_exit; + } + + unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename)); + unix_convert(filename, conn, NULL, &bad_path, &st); + fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY), + (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action); + + if (!fsp) { + /* Perhaps it is a directory */ + if (errno == EISDIR) + fsp = open_directory(conn, filename, &st, + (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action); + + if (!fsp) { + DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename)); + r_u->status = ERROR_ACCESS_DENIED; + goto error_exit; + } + } + + sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd); + + if (sd_size == 0) { + DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename)); + r_u->status = ERROR_ACCESS_DENIED; + goto error_exit; + } + + r_u->ptr_response = 1; + r_u->size_response = sd_size; + r_u->ptr_secdesc = 1; + r_u->size_secdesc = sd_size; + r_u->sec_desc = psd; + + psd->dacl->revision = (uint16) NT4_ACL_REVISION; + + close_file(fsp, True); + + close_cnum(conn, user.vuid); + return r_u->status; + + error_exit: + + if(fsp) { + close_file(fsp, True); + } + + if (conn) + close_cnum(conn, user.vuid); + + return r_u->status; +} + +/*********************************************************************************** + Win9x NT tools set security descriptor. +***********************************************************************************/ + +uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u, + SRV_R_NET_FILE_SET_SECDESC *r_u) +{ + BOOL ret; + pstring filename; + pstring qualname; + fstring null_pw; + files_struct *fsp = NULL; + SMB_STRUCT_STAT st; + BOOL bad_path; + int access_mode; + int action; + int ecode; + struct current_user user; + fstring user_name; + connection_struct *conn = NULL; + + ZERO_STRUCT(st); + + r_u->status = NT_STATUS_NOPROBLEMO; + + unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname)); + + /* Null password is ok - we are already an authenticated user... */ + *null_pw = '\0'; + + get_current_user(&user, p); + fstrcpy(user_name, uidtoname(user.uid)); + + conn = make_connection(qualname, user_name, null_pw, 0, "A:", user.vuid, &ecode); + + if (conn == NULL) { + DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname)); + r_u->status = (uint32)ecode; + goto error_exit; + } + + unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename)); + unix_convert(filename, conn, NULL, &bad_path, &st); + + fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR), + (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action); + + if (!fsp) { + /* Perhaps it is a directory */ + if (errno == EISDIR) + fsp = open_directory(conn, filename, &st, + (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action); + + if (!fsp) { + DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename)); + r_u->status = ERROR_ACCESS_DENIED; + goto error_exit; + } + } + + ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc); + + if (ret == False) { + DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename)); + r_u->status = ERROR_ACCESS_DENIED; + goto error_exit; + } + + close_file(fsp, True); + close_cnum(conn, user.vuid); + return r_u->status; + + error_exit: + + if(fsp) { + close_file(fsp, True); + } + + if (conn) + close_cnum(conn, user.vuid); + + return r_u->status; +} + +/*********************************************************************************** + It may be that we want to limit users to creating shares on certain areas of the UNIX file area. + We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy. + These disks would the disks listed by this function. + Users could then create shares relative to these disks. Watch out for moving these disks around. + "Nigel Williams" <nigel@veritas.com>. +***********************************************************************************/ + +const char *server_disks[] = {"C:"}; + +static uint32 get_server_disk_count(void) +{ + return sizeof(server_disks)/sizeof(server_disks[0]); +} + +static uint32 init_server_disk_enum(uint32 *resume) +{ + uint32 server_disk_count = get_server_disk_count(); + + /*resume can be an offset into the list for now*/ + + if(*resume & 0x80000000) + *resume = 0; + + if(*resume > server_disk_count) + *resume = server_disk_count; + + return server_disk_count - *resume; +} + +static const char *next_server_disk_enum(uint32 *resume) +{ + const char *disk; + + if(init_server_disk_enum(resume) == 0) + return NULL; + + disk = server_disks[*resume]; + + (*resume)++; + + DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume)); + + return disk; +} + +uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u) +{ + uint32 i; + const char *disk_name; + uint32 resume=get_enum_hnd(&q_u->enum_hnd); + + r_u->status=NT_STATUS_NOPROBLEMO; + + r_u->total_entries = init_server_disk_enum(&resume); + + r_u->disk_enum_ctr.unknown = 0; + + r_u->disk_enum_ctr.disk_info_ptr = (uint32) r_u->disk_enum_ctr.disk_info; + + /*allow one DISK_INFO for null terminator*/ + + for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) { + + r_u->disk_enum_ctr.entries_read++; + + /*copy disk name into a unicode string*/ + + init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name); + } + + /*add a terminating null string. Is this there if there is more data to come?*/ + + r_u->disk_enum_ctr.entries_read++; + + init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, ""); + + init_enum_hnd(&r_u->enum_hnd, resume); + + return r_u->status; +} + +uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u) +{ + int snum; + fstring share_name; + + r_u->status=NT_STATUS_NOPROBLEMO; + + switch(q_u->type) { + + case 0x9: + + /*check if share name is ok*/ + /*also check if we already have a share with this name*/ + + unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name)); + snum = find_service(share_name); + + /* Share already exists. */ + if (snum >= 0) + r_u->status = NT_STATUS_OBJECT_NAME_INVALID; + break; + + default: + /*unsupported type*/ + r_u->status = ERROR_INVALID_LEVEL; + break; + } + + return r_u->status; +} diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c index f107f1f2af9..8f15b7f117b 100644 --- a/source/rpc_server/srv_util.c +++ b/source/rpc_server/srv_util.c @@ -162,8 +162,12 @@ void get_domain_user_groups(char *domain_groups, char *user) if (domain_groups == NULL || user == NULL) return; +#if 0 /* removed by --jerry */ /* any additional groups this user is in. e.g power users */ pstrcpy(domain_groups, lp_domain_groups()); +#else + *domain_groups = '\0'; +#endif /* can only be a user or a guest. cannot be guest _and_ admin */ if (user_in_list(user, lp_domain_guest_group())) diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c index a574f2e128a..153d5366e00 100644 --- a/source/rpcclient/cmd_lsarpc.c +++ b/source/rpcclient/cmd_lsarpc.c @@ -34,12 +34,19 @@ static uint32 cmd_lsa_query_info_policy(struct cli_state *cli, int argc, char ** DOM_SID dom_sid; fstring sid_str, domain_name; uint32 info_class = 3; + TALLOC_CTX *mem_ctx; if (argc > 2) { printf("Usage: %s [info_class]\n", argv[0]); return 0; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_lsa_query_info_poicy: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + if (argc == 2) { info_class = atoi(argv[1]); } @@ -50,7 +57,7 @@ static uint32 cmd_lsa_query_info_policy(struct cli_state *cli, int argc, char ** return NT_STATUS_UNSUCCESSFUL; } - if ((result = cli_lsa_open_policy(cli, True, + if ((result = cli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -60,7 +67,7 @@ static uint32 cmd_lsa_query_info_policy(struct cli_state *cli, int argc, char ** /* Lookup info policy */ - if ((result = cli_lsa_query_info_policy(cli, &pol, info_class, + if ((result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, domain_name, &dom_sid)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -73,10 +80,11 @@ static uint32 cmd_lsa_query_info_policy(struct cli_state *cli, int argc, char ** done: if (got_policy_hnd) { - cli_lsa_close(cli, &pol); + cli_lsa_close(cli, mem_ctx, &pol); } cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -91,12 +99,19 @@ static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv) DOM_SID *sids; uint32 *types; int num_names, i; + TALLOC_CTX *mem_ctx; if (argc == 1) { printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]); return 0; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_lsa_lookup_names: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_LSARPC)) { fprintf (stderr, "Could not initialize samr pipe!\n"); @@ -104,7 +119,7 @@ static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv) } - if ((result = cli_lsa_open_policy(cli, True, + if ((result = cli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -114,8 +129,8 @@ static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv) /* Lookup the names */ - if ((result = cli_lsa_lookup_names( - cli, &pol, argc - 1, &argv[1], &sids, &types, &num_names) != + if ((result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1, + &argv[1], &sids, &types, &num_names) != NT_STATUS_NOPROBLEMO)) { goto done; } @@ -130,16 +145,19 @@ static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv) types[i]); } +#if 0 /* JERRY */ safe_free(sids); safe_free(types); +#endif done: if (got_policy_hnd) { - cli_lsa_close(cli, &pol); + cli_lsa_close(cli, mem_ctx, &pol); } cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -155,19 +173,26 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv) char **names; uint32 *types; int num_names, i; + TALLOC_CTX *mem_ctx; if (argc == 1) { printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]); return 0; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_lsa_lookup_sids: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_LSARPC)) { fprintf (stderr, "Could not initialize samr pipe!\n"); return NT_STATUS_UNSUCCESSFUL; } - if ((result = cli_lsa_open_policy(cli, True, + if ((result = cli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -177,7 +202,7 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv) /* Convert arguments to sids */ - sids = (DOM_SID *)malloc(sizeof(DOM_SID) * (argc - 1)); + sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * (argc - 1)); if (!sids) { printf("out of memory\n"); @@ -190,7 +215,7 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv) /* Lookup the SIDs */ - if ((result = cli_lsa_lookup_sids(cli, &pol, argc - 1, sids, + if ((result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, &names, &types, &num_names) != NT_STATUS_NOPROBLEMO)) { goto done; @@ -206,6 +231,7 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv) "*unknown*", types[i]); } +#if 0 /* JERRY */ safe_free(sids); safe_free(types); @@ -214,14 +240,16 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv) } safe_free(names); +#endif done: if (got_policy_hnd) { - cli_lsa_close(cli, &pol); + cli_lsa_close(cli, mem_ctx, &pol); } cli_nt_session_close(cli); + talloc_destroy (mem_ctx); return result; } @@ -238,19 +266,26 @@ static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **arg uint32 enum_ctx = 0; uint32 num_domains; int i; + TALLOC_CTX *mem_ctx; if (argc != 1) { printf("Usage: %s\n", argv[0]); return 0; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_lsa_enum_trust_dom: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_LSARPC)) { fprintf (stderr, "Could not initialize samr pipe!\n"); return NT_STATUS_UNSUCCESSFUL; } - if ((result = cli_lsa_open_policy(cli, True, + if ((result = cli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -260,7 +295,7 @@ static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **arg /* Lookup list of trusted domains */ - if ((result = cli_lsa_enum_trust_dom(cli, &pol, &enum_ctx, + if ((result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx, &num_domains, &domain_names, &domain_sids) != NT_STATUS_NOPROBLEMO)) { @@ -277,6 +312,7 @@ static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **arg "*unknown*", sid_str); } +#if 0 /* JERRY */ safe_free(domain_sids); for (i = 0; i < num_domains; i++) { @@ -284,14 +320,16 @@ static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **arg } safe_free(domain_names); +#endif done: if (got_policy_hnd) { - cli_lsa_close(cli, &pol); + cli_lsa_close(cli, mem_ctx, &pol); } cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c index b3d135275a7..931d44eb3b1 100644 --- a/source/rpcclient/cmd_samr.c +++ b/source/rpcclient/cmd_samr.c @@ -5,8 +5,8 @@ Copyright (C) Andrew Tridgell 1992-2000, Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Elrond 2000 - Copyright (C) Tim Potter 2000 + Copyright (C) Elrond 2000, + Copyright (C) Tim Potter 2000 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,6 +94,31 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr) } } +static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2) +{ + fstring name; + + unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1); + printf("Domain:\t%s\n", name); + + unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1); + printf("Server:\t%s\n", name); + + printf("Total Users:\t%d\n", info2->num_domain_usrs); + printf("Total Groups:\t%d\n", info2->num_domain_grps); + printf("Total Aliases:\t%d\n", info2->num_local_grps); + + printf("Sequence No:\t%d\n", info2->seq_num); + + printf("Unknown 0:\t0x%x\n", info2->unknown_0); + printf("Unknown 1:\t0x%x\n", info2->unknown_1); + printf("Unknown 2:\t0x%x\n", info2->unknown_2); + printf("Unknown 3:\t0x%x\n", info2->unknown_3); + printf("Unknown 4:\t0x%x\n", info2->unknown_4); + printf("Unknown 5:\t0x%x\n", info2->unknown_5); + printf("Unknown 6:\t0x%x\n", info2->unknown_6); +} + /********************************************************************** * Query user information */ @@ -108,11 +133,24 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) SAM_USERINFO_CTR user_ctr; SAM_USER_INFO_21 info_21; fstring server; + TALLOC_CTX *mem_ctx; + uint32 user_rid; - if (argc != 1) { - printf("Usage: %s\n", argv[0]); + + if (argc != 2) { + printf("Usage: %s rid\n", argv[0]); return 0; } + + sscanf(argv[1], "%i", &user_rid); + + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_samr_query_user: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + fetch_domain_sid(cli); /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SAMR)) { @@ -123,16 +161,15 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, + if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { goto done; } got_connect_pol = True; - fetch_domain_sid(cli); - if ((result = cli_samr_open_domain(cli, &connect_pol, + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol)) != NT_STATUS_NOPROBLEMO) { @@ -141,9 +178,9 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) got_domain_pol = True; - if ((result = cli_samr_open_user(cli, &domain_pol, + if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol, MAXIMUM_ALLOWED_ACCESS, - 0x1f4, &user_pol)) + user_rid, &user_pol)) != NT_STATUS_NOPROBLEMO) { goto done; } @@ -155,7 +192,7 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) user_ctr.info.id21 = &info_21; - if ((result = cli_samr_query_userinfo(cli, &user_pol, info_level, + if ((result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, info_level, &user_ctr)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -164,11 +201,12 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv) display_sam_user_info_21(&info_21); done: - if (got_user_pol) cli_samr_close(cli, &user_pol); - if (got_domain_pol) cli_samr_close(cli, &domain_pol); - if (got_connect_pol) cli_samr_close(cli, &connect_pol); + if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol); + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -227,12 +265,21 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) got_group_pol = False; GROUP_INFO_CTR group_ctr; fstring server; + TALLOC_CTX *mem_ctx; if (argc != 1) { printf("Usage: %s\n", argv[0]); return 0; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_samr_query_group: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + fetch_domain_sid(cli); + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SAMR)) { fprintf (stderr, "Could not initialize samr pipe!\n"); @@ -242,16 +289,15 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, + if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { goto done; } got_connect_pol = True; - fetch_domain_sid(cli); - if ((result = cli_samr_open_domain(cli, &connect_pol, + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol)) != NT_STATUS_NOPROBLEMO) { @@ -260,7 +306,7 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) got_domain_pol = True; - if ((result = cli_samr_open_group(cli, &domain_pol, + if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol, MAXIMUM_ALLOWED_ACCESS, 0x202, &group_pol)) != NT_STATUS_NOPROBLEMO) { @@ -271,7 +317,7 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) ZERO_STRUCT(group_ctr); - if ((result = cli_samr_query_groupinfo(cli, &group_pol, info_level, + if ((result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol, info_level, &group_ctr)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -280,11 +326,12 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv) display_group_info_ctr(&group_ctr); done: - if (got_group_pol) cli_samr_close(cli, &group_pol); - if (got_domain_pol) cli_samr_close(cli, &domain_pol); - if (got_connect_pol) cli_samr_close(cli, &connect_pol); + if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol); + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -305,14 +352,23 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char ** DOM_GID *user_gids; int i; fstring server; + TALLOC_CTX *mem_ctx; if (argc != 2) { printf("Usage: %s rid\n", argv[0]); return 0; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_samr_query_usergroups: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + sscanf(argv[1], "%i", &user_rid); + fetch_domain_sid(cli); + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SAMR)) { fprintf (stderr, "Could not initialize samr pipe!\n"); @@ -322,16 +378,15 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char ** slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, + if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { goto done; } got_connect_pol = True; - fetch_domain_sid(cli); - if ((result = cli_samr_open_domain(cli, &connect_pol, + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol)) != NT_STATUS_NOPROBLEMO) { @@ -340,7 +395,7 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char ** got_domain_pol = True; - if ((result = cli_samr_open_user(cli, &domain_pol, + if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol, MAXIMUM_ALLOWED_ACCESS, user_rid, &user_pol)) != NT_STATUS_NOPROBLEMO) { @@ -349,7 +404,7 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char ** got_user_pol = True; - if ((result = cli_samr_query_usergroups(cli, &user_pol, + if ((result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol, &num_groups, &user_gids)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -361,11 +416,12 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char ** } done: - if (got_user_pol) cli_samr_close(cli, &user_pol); - if (got_domain_pol) cli_samr_close(cli, &domain_pol); - if (got_connect_pol) cli_samr_close(cli, &connect_pol); + if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol); + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -382,14 +438,23 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar uint32 num_members, *group_rids, *group_attrs, group_rid; int i; fstring server; + TALLOC_CTX *mem_ctx; if (argc != 2) { printf("Usage: %s rid\n", argv[0]); return 0; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_samr_query_groupmem: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + sscanf(argv[1], "%i", &group_rid); + fetch_domain_sid(cli); + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SAMR)) { fprintf (stderr, "Could not initialize samr pipe!\n"); @@ -399,16 +464,15 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - if ((result = cli_samr_connect(cli, server, MAXIMUM_ALLOWED_ACCESS, + if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS, &connect_pol)) != NT_STATUS_NOPROBLEMO) { goto done; } got_connect_pol = True; - fetch_domain_sid(cli); - if ((result = cli_samr_open_domain(cli, &connect_pol, + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol)) != NT_STATUS_NOPROBLEMO) { @@ -417,7 +481,7 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar got_domain_pol = True; - if ((result = cli_samr_open_group(cli, &domain_pol, + if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol, MAXIMUM_ALLOWED_ACCESS, group_rid, &group_pol)) != NT_STATUS_NOPROBLEMO) { @@ -426,7 +490,7 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar got_group_pol = True; - if ((result = cli_samr_query_groupmem(cli, &group_pol, + if ((result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol, &num_members, &group_rids, &group_attrs)) != NT_STATUS_NOPROBLEMO) { @@ -439,11 +503,361 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar } done: - if (got_group_pol) cli_samr_close(cli, &group_pol); - if (got_domain_pol) cli_samr_close(cli, &domain_pol); - if (got_connect_pol) cli_samr_close(cli, &connect_pol); + if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol); + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); + + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + +/* Enumerate domain groups */ + +static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc, + char **argv) +{ + POLICY_HND connect_pol, domain_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + BOOL got_connect_pol = False, got_domain_pol = False; + TALLOC_CTX *mem_ctx; + fstring server; + uint32 start_idx, size, num_dom_groups, i; + struct acct_info *dom_groups; + + if (argc != 1) { + printf("Usage: %s\n", argv[0]); + return 0; + } + + if (!(mem_ctx = talloc_init())) { + DEBUG(0, ("cmd_samr_enum_dom_groups: talloc_init returned " + "NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + fetch_domain_sid(cli); + + /* Initialise RPC connection */ + + if (!cli_nt_session_open (cli, PIPE_SAMR)) { + fprintf (stderr, "Could not initialize samr pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper(server); + + /* Get sam policy handle */ + + if ((result = cli_samr_connect(cli, mem_ctx, server, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + + /* Get domain policy handle */ + + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + /* Enumerate domain groups */ + + start_idx = 0; + size = 0xffff; + + result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol, + &start_idx, size, + &dom_groups, &num_dom_groups); + + for (i = 0; i < num_dom_groups; i++) + printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name, + dom_groups[i].rid); + + done: + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + +/* Query alias membership */ + +static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc, + char **argv) +{ + POLICY_HND connect_pol, domain_pol, alias_pol; + BOOL got_connect_pol = False, got_domain_pol = False, + got_alias_pol = False; + TALLOC_CTX *mem_ctx; + uint32 result = NT_STATUS_UNSUCCESSFUL, alias_rid, num_members, i; + DOM_SID *alias_sids; + + fstring server; + + if (argc != 2) { + printf("Usage: %s rid\n", argv[0]); + return 0; + } + + if (!(mem_ctx=talloc_init())) { + DEBUG(0,("cmd_samr_query_aliasmem: talloc_init() " + "returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + sscanf(argv[1], "%i", &alias_rid); + + /* Initialise RPC connection */ + + fetch_domain_sid(cli); + + if (!cli_nt_session_open (cli, PIPE_SAMR)) { + fprintf (stderr, "Could not initialize samr pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + /* Open SAMR handle */ + + slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper(server); + + if ((result = cli_samr_connect(cli, mem_ctx, server, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + + /* Open handle on domain */ + + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + /* Open handle on alias */ + + if ((result = cli_samr_open_alias(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + alias_rid, &alias_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_alias_pol = True; + + if ((result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol, + &num_members, &alias_sids)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + for (i = 0; i < num_members; i++) { + fstring sid_str; + + sid_to_string(sid_str, &alias_sids[i]); + printf("\tsid:[%s]\n", sid_str); + } + + done: + if (got_alias_pol) cli_samr_close(cli, mem_ctx, &alias_pol); + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); + + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + +/* Query display info */ + +static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc, + char **argv) +{ + POLICY_HND connect_pol, domain_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + BOOL got_connect_pol = False, got_domain_pol = False; + TALLOC_CTX *mem_ctx; + fstring server; + uint32 start_idx, size, num_dom_groups, i; + struct acct_info *dom_groups; + + if (argc != 1) { + printf("Usage: %s\n", argv[0]); + return 0; + } + + if (!(mem_ctx = talloc_init())) { + DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned " + "NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + fetch_domain_sid(cli); + + /* Initialise RPC connection */ + + if (!cli_nt_session_open (cli, PIPE_SAMR)) { + fprintf (stderr, "Could not initialize samr pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper(server); + + /* Get sam policy handle */ + + if ((result = cli_samr_connect(cli, mem_ctx, server, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) != + NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + + /* Get domain policy handle */ + + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + /* Query display info */ + + start_idx = 0; + size = 0xffff; + + result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol, + &start_idx, size, + &dom_groups, &num_dom_groups); + + for (i = 0; i < num_dom_groups; i++) + printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name, + dom_groups[i].rid); + + done: + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); + + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return result; +} + +/* Query domain info */ + +static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc, + char **argv) +{ + POLICY_HND connect_pol, domain_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + BOOL got_connect_pol = False, got_domain_pol = False; + TALLOC_CTX *mem_ctx; + fstring server; + uint16 switch_value = 2; + SAM_UNK_CTR ctr; + + if (argc > 2) { + printf("Usage: %s [infolevel\n", argv[0]); + return 0; + } + + if (argc == 2) + switch_value = atoi(argv[1]); + + if (!(mem_ctx = talloc_init())) { + DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned " + "NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + fetch_domain_sid(cli); + + /* Initialise RPC connection */ + + if (!cli_nt_session_open (cli, PIPE_SAMR)) { + fprintf (stderr, "Could not initialize samr pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper(server); + + /* Get sam policy handle */ + + if ((result = cli_samr_connect(cli, mem_ctx, server, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_connect_pol = True; + + /* Get domain policy handle */ + + if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &domain_sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + got_domain_pol = True; + + /* Query domain info */ + + if ((result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol, + switch_value, &ctr)) + != NT_STATUS_NOPROBLEMO) { + goto done; + } + + /* Display domain info */ + + switch (switch_value) { + case 2: + display_sam_unk_info_2(&ctr.info.inf2); + break; + default: + printf("cannot display domain info for switch value %d\n", + switch_value); + break; + } + + done: + if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol); + if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol); + + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -452,10 +866,16 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar struct cmd_set samr_commands[] = { { "SAMR", NULL, "" }, + { "queryuser", cmd_samr_query_user, "Query user info" }, { "querygroup", cmd_samr_query_group, "Query group info" }, { "queryusergroups", cmd_samr_query_usergroups, "Query user groups" }, { "querygroupmem", cmd_samr_query_groupmem, "Query group membership" }, + { "queryaliasmem", cmd_samr_query_aliasmem, "Query alias membership" }, + { "querydispinfo", cmd_samr_query_dispinfo, "Query display info" }, + { "querydominfo", cmd_samr_query_dominfo, "Query domain info" }, + { "enumdomgroups", cmd_samr_enum_dom_groups, "Enumerate domain groups" }, + { NULL, NULL, NULL } }; diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c index 52ff8b2cdfe..6b5d45a2492 100644 --- a/source/rpcclient/cmd_spoolss.c +++ b/source/rpcclient/cmd_spoolss.c @@ -146,8 +146,9 @@ static uint32 cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char { uint32 result = NT_STATUS_UNSUCCESSFUL; pstring printername; - fstring server, user; + fstring servername, user; POLICY_HND hnd; + TALLOC_CTX *mem_ctx; if (argc != 2) { printf("Usage: %s <printername>\n", argv[0]); @@ -156,10 +157,16 @@ static uint32 cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char if (!cli) return NT_STATUS_UNSUCCESSFUL; - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_open_printer_ex: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + + slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (servername); fstrcpy (user, cli->user_name); fstrcpy (printername, argv[1]); @@ -171,18 +178,19 @@ static uint32 cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char } /* Open the printer handle */ - result = cli_spoolss_open_printer_ex (cli, printername, "", - MAXIMUM_ALLOWED_ACCESS, server, user, &hnd); + result = cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "", + MAXIMUM_ALLOWED_ACCESS, servername, user, &hnd); if (result == NT_STATUS_NOPROBLEMO) { printf ("Printer %s opened successfully\n", printername); - result = cli_spoolss_close_printer (cli, &hnd); + result = cli_spoolss_close_printer (cli, mem_ctx, &hnd); if (result != NT_STATUS_NOPROBLEMO) { printf ("Error closing printer handle! (%s)\n", get_nt_error_msg(result)); } } cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -194,13 +202,13 @@ printer info level 0 display function static void display_print_info_0(PRINTER_INFO_0 *i1) { fstring name; - fstring the_server; + fstring servername; unistr_to_ascii(name, i1->printername.buffer, sizeof(name) - 1); - unistr_to_ascii(the_server, i1->servername.buffer, sizeof(the_server) - 1); + unistr_to_ascii(servername, i1->servername.buffer, sizeof(servername) - 1); printf("\tprintername:[%s]\n", name); - printf("\tservername:[%s]\n", the_server); + printf("\tservername:[%s]\n", servername); printf("\tcjobs:[0x%x]\n", i1->cjobs); printf("\ttotal_jobs:[0x%x]\n", i1->total_jobs); @@ -335,14 +343,22 @@ static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char ** info_level = 1; PRINTER_INFO_CTR ctr; int returned; - uint32 i; - + uint32 i = 0; + TALLOC_CTX *mem_ctx; + if (argc > 2) { printf("Usage: %s [level]\n", argv[0]); return NT_STATUS_NOPROBLEMO; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_enum_printers: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + if (argc == 2) { info_level = atoi(argv[1]); } @@ -356,10 +372,14 @@ static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char ** /* Enumerate printers -- Should we enumerate types other than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */ ZERO_STRUCT(ctr); - result = cli_spoolss_enum_printers(cli, PRINTER_ENUM_LOCAL, + result = cli_spoolss_enum_printers(cli, mem_ctx, PRINTER_ENUM_LOCAL, info_level, &returned, &ctr); - if (result == NT_STATUS_NOPROBLEMO) { + if (result == NT_STATUS_NOPROBLEMO) + { + if (!returned) + printf ("No Printers printers returned.\n"); + switch(info_level) { case 0: for (i=0; i<returned; i++) { @@ -388,6 +408,7 @@ static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char ** } cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -429,11 +450,19 @@ static uint32 cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **arg info_level = 1; PORT_INFO_CTR ctr; int returned; + TALLOC_CTX *mem_ctx; if (argc > 2) { printf("Usage: %s [level]\n", argv[0]); return NT_STATUS_NOPROBLEMO; } + + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_enum_ports: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + if (argc == 2) { info_level = atoi(argv[1]); @@ -448,7 +477,7 @@ static uint32 cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **arg /* Enumerate ports */ ZERO_STRUCT(ctr); - result = cli_spoolss_enum_ports(cli, info_level, &returned, &ctr); + result = cli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr); if (result == NT_STATUS_NOPROBLEMO) { int i; @@ -469,6 +498,7 @@ static uint32 cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **arg } cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -485,13 +515,21 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg PRINTER_INFO_CTR ctr; fstring printername, servername, - username; + user; + TALLOC_CTX *mem_ctx; if (argc == 1 || argc > 3) { printf("Usage: %s <printername> [level]\n", argv[0]); return NT_STATUS_NOPROBLEMO; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_getprinter: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) { fprintf (stderr, "Could not initialize spoolss pipe!\n"); @@ -506,19 +544,19 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (servername); slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]); - fstrcpy (username, cli->user_name); + fstrcpy (user, cli->user_name); /* get a printer handle */ if ((result = cli_spoolss_open_printer_ex( - cli, printername, "", MAXIMUM_ALLOWED_ACCESS, servername, - username, &pol)) != NT_STATUS_NOPROBLEMO) { + cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, servername, + user, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; } opened_hnd = True; /* Get printer info */ - if ((result = cli_spoolss_getprinter(cli, &pol, info_level, &ctr)) + if ((result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr)) != NT_STATUS_NOPROBLEMO) { goto done; } @@ -545,9 +583,10 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg done: if (opened_hnd) - cli_spoolss_close_printer(cli, &pol); + cli_spoolss_close_printer(cli, mem_ctx, &pol); cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return result; } @@ -673,9 +712,10 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv BOOL opened_hnd = False; PRINTER_DRIVER_CTR ctr; fstring printername, - server, + servername, user; uint32 i; + TALLOC_CTX *mem_ctx; if ((argc == 1) || (argc > 3)) { @@ -683,6 +723,12 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv return NT_STATUS_NOPROBLEMO; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_getdriver: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) { @@ -691,16 +737,16 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv } /* get the arguments need to open the printer handle */ - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); + slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (servername); fstrcpy (user, cli->user_name); fstrcpy (printername, argv[1]); if (argc == 3) info_level = atoi(argv[2]); /* Open a printer handle */ - if ((result=cli_spoolss_open_printer_ex (cli, printername, "", - MAXIMUM_ALLOWED_ACCESS, server, user, &pol)) != NT_STATUS_NO_PROBLEMO) + if ((result=cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "", + MAXIMUM_ALLOWED_ACCESS, servername, user, &pol)) != NT_STATUS_NO_PROBLEMO) { printf ("Error opening printer handle for %s!\n", printername); return result; @@ -711,7 +757,7 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv /* loop through and print driver info level for each architecture */ for (i=0; archi_table[i].long_archi!=NULL; i++) { - result = cli_spoolss_getprinterdriver (cli, &pol, info_level, + result = cli_spoolss_getprinterdriver (cli, mem_ctx, &pol, info_level, archi_table[i].long_archi, &ctr); switch (result) @@ -753,8 +799,9 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv /* cleanup */ if (opened_hnd) - cli_spoolss_close_printer (cli, &pol); + cli_spoolss_close_printer (cli, mem_ctx, &pol); cli_nt_session_close (cli); + talloc_destroy(mem_ctx); if (result==ERROR_UNKNOWN_PRINTER_DRIVER) return NT_STATUS_NO_PROBLEMO; @@ -771,9 +818,10 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a uint32 result=0, info_level = 1; PRINTER_DRIVER_CTR ctr; - fstring server; + fstring servername; uint32 i, j, returned; + TALLOC_CTX *mem_ctx; if (argc > 2) { @@ -781,6 +829,12 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a return NT_STATUS_NOPROBLEMO; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_enum_drivers: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) { @@ -789,8 +843,8 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a } /* get the arguments need to open the printer handle */ - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); + slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (servername); if (argc == 2) info_level = atoi(argv[1]); @@ -799,7 +853,7 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a for (i=0; archi_table[i].long_archi!=NULL; i++) { returned = 0; - result = cli_spoolss_enumprinterdrivers (cli, info_level, + result = cli_spoolss_enumprinterdrivers (cli, mem_ctx, info_level, archi_table[i].long_archi, &returned, &ctr); if (returned == 0) @@ -841,6 +895,7 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a /* cleanup */ cli_nt_session_close (cli); + talloc_destroy(mem_ctx); if (result==ERROR_UNKNOWN_PRINTER_DRIVER) return NT_STATUS_NO_PROBLEMO; @@ -871,6 +926,7 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a uint32 result; fstring env; DRIVER_DIRECTORY_CTR ctr; + TALLOC_CTX *mem_ctx; if (argc > 2) { @@ -884,6 +940,13 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a fprintf (stderr, "Could not initialize spoolss pipe!\n"); return NT_STATUS_UNSUCCESSFUL; } + + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_getdriverdir: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + /* get the arguments need to open the printer handle */ if (argc == 2) @@ -892,7 +955,7 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a fstrcpy (env, "Windows NT x86"); /* Get the directory. Only use Info level 1 */ - if ((result = cli_spoolss_getprinterdriverdir (cli, 1, env, &ctr)) + if ((result = cli_spoolss_getprinterdriverdir (cli, mem_ctx, 1, env, &ctr)) != NT_STATUS_NO_PROBLEMO) { return result; @@ -903,6 +966,7 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a /* cleanup */ cli_nt_session_close (cli); + talloc_destroy(mem_ctx); return result; @@ -966,7 +1030,11 @@ static char* get_driver_3_param (char* str, char* delim, UNISTR* dest) <Config File Name>:<Help File Name>:<Language Monitor Name>:\ <Default Data Type>:<Comma Separated list of Files> *******************************************************************************/ -static BOOL init_drv_info_3_members (DRIVER_INFO_3 *info, char *args) +static BOOL init_drv_info_3_members ( + TALLOC_CTX *mem_ctx, + DRIVER_INFO_3 *info, + char *args +) { char *str, *str2; uint32 len, i; @@ -997,7 +1065,7 @@ static BOOL init_drv_info_3_members (DRIVER_INFO_3 *info, char *args) /* allocate the space; add one extra slot for a terminating NULL. Each filename is NULL terminated and the end contains a double NULL */ - if ((info->dependentfiles=(uint16*)malloc((len+1)*sizeof(uint16))) == NULL) + if ((info->dependentfiles=(uint16*)talloc(mem_ctx, (len+1)*sizeof(uint16))) == NULL) { DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n")); return False; @@ -1020,6 +1088,7 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha DRIVER_INFO_3 info3; fstring arch; fstring driver_name; + TALLOC_CTX *mem_ctx = NULL; /* parse the command arguements */ if (argc != 3) @@ -1031,6 +1100,12 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha return NT_STATUS_NOPROBLEMO; } + + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_addprinterdriver: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) @@ -1050,16 +1125,15 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha else set_drv_info_3_env(&info3, arch); - if (!init_drv_info_3_members(&info3, argv[2])) + if (!init_drv_info_3_members(mem_ctx, &info3, argv[2])) { printf ("Error Invalid parameter list - %s.\n", argv[2]); return NT_STATUS_INVALID_PARAMETER; } - /* Get the directory. Only use Info level 1 */ ctr.info3 = &info3; - if ((result = cli_spoolss_addprinterdriver (cli, level, &ctr)) + if ((result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr)) != NT_STATUS_NO_PROBLEMO) { return result; @@ -1070,6 +1144,7 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha /* cleanup */ cli_nt_session_close (cli); + talloc_destroy(mem_ctx); return result; @@ -1082,7 +1157,8 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char ** level = 2; PRINTER_INFO_CTR ctr; PRINTER_INFO_2 info2; - fstring server; + fstring servername; + TALLOC_CTX *mem_ctx = NULL; /* parse the command arguements */ if (argc != 5) @@ -1090,9 +1166,16 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char ** printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]); return NT_STATUS_NOPROBLEMO; } + + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_addprinterex: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); + + slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (servername); /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) @@ -1105,7 +1188,7 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char ** /* Fill in the DRIVER_INFO_3 struct */ ZERO_STRUCT(info2); #if 0 /* JERRY */ - init_unistr( &info2.servername, server); + init_unistr( &info2.servername, servername); #endif init_unistr( &info2.printername, argv[1]); init_unistr( &info2.sharename, argv[2]); @@ -1130,11 +1213,8 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char ** info2.averageppm = 0; */ - - - /* Get the directory. Only use Info level 1 */ ctr.printers_2 = &info2; - if ((result = cli_spoolss_addprinterex (cli, level, &ctr)) + if ((result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr)) != NT_STATUS_NO_PROBLEMO) { cli_nt_session_close (cli); @@ -1145,6 +1225,7 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char ** /* cleanup */ cli_nt_session_close (cli); + talloc_destroy(mem_ctx); return result; @@ -1160,7 +1241,8 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg PRINTER_INFO_2 info2; fstring servername, printername, - username; + user; + TALLOC_CTX *mem_ctx = NULL; /* parse the command arguements */ if (argc != 3) @@ -1169,10 +1251,16 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg return NT_STATUS_NOPROBLEMO; } + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_setdriver: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (servername); slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]); - fstrcpy (username, cli->user_name); + fstrcpy (user, cli->user_name); /* Initialise RPC connection */ if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) @@ -1183,8 +1271,8 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg /* get a printer handle */ - if ((result = cli_spoolss_open_printer_ex(cli, printername, "", - MAXIMUM_ALLOWED_ACCESS, servername, username, &pol)) + if ((result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "", + MAXIMUM_ALLOWED_ACCESS, servername, user, &pol)) != NT_STATUS_NOPROBLEMO) { goto done; @@ -1195,15 +1283,15 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg /* Get printer info */ ZERO_STRUCT (info2); ctr.printers_2 = &info2; - if ((result = cli_spoolss_getprinter(cli, &pol, level, &ctr)) != NT_STATUS_NOPROBLEMO) + if ((result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr)) != NT_STATUS_NOPROBLEMO) { - printf ("Unable to retreive printer information!\n"); + printf ("Unable to retrieve printer information!\n"); goto done; } /* set the printer driver */ init_unistr(&ctr.printers_2->drivername, argv[2]); - if ((result = cli_spoolss_setprinter(cli, &pol, level, &ctr, 0)) != NT_STATUS_NO_PROBLEMO) + if ((result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0)) != NT_STATUS_NO_PROBLEMO) { printf ("SetPrinter call failed!\n"); goto done;; @@ -1214,19 +1302,74 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg done: /* cleanup */ if (opened_hnd) - cli_spoolss_close_printer(cli, &pol); + cli_spoolss_close_printer(cli, mem_ctx, &pol); cli_nt_session_close (cli); + talloc_destroy(mem_ctx); return result; } +static uint32 cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **argv) +{ + uint32 result = NT_STATUS_UNSUCCESSFUL; + fstring servername; + TALLOC_CTX *mem_ctx = NULL; + int i; + + /* parse the command arguements */ + if (argc != 2) + { + printf ("Usage: %s <driver>\n", argv[0]); + return NT_STATUS_NOPROBLEMO; + } + + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("cmd_spoolss_deletedriver: talloc_init returned NULL!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (servername); + + /* Initialise RPC connection */ + if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) + { + fprintf (stderr, "Could not initialize spoolss pipe!\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + /* delete the driver for all architectures */ + for (i=0; archi_table[i].long_archi; i++) + { + /* make the call to remove the driver */ + if ((result = cli_spoolss_deleteprinterdriver(cli, mem_ctx, + archi_table[i].long_archi, argv[1])) != NT_STATUS_NO_PROBLEMO) + { + printf ("Failed to remove driver %s for arch [%s] - error %s!\n", + argv[1], archi_table[i].long_archi, get_nt_error_msg(result)); + } + else + printf ("Driver %s removed for arch [%s].\n", argv[1], archi_table[i].long_archi); + } + + + /* cleanup */ + cli_nt_session_close (cli); + talloc_destroy(mem_ctx); + + return NT_STATUS_NO_PROBLEMO; +} + + /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { { "SPOOLSS", NULL, "" }, { "adddriver", cmd_spoolss_addprinterdriver, "Add a print driver" }, { "addprinter", cmd_spoolss_addprinterex, "Add a printer" }, + { "deldriver", cmd_spoolss_deletedriver, "Delete a printer driver" }, { "enumdata", cmd_spoolss_not_implemented, "Enumerate printer data (*)" }, { "enumjobs", cmd_spoolss_not_implemented, "Enumerate print jobs (*)" }, { "enumports", cmd_spoolss_enum_ports, "Enumerate printer ports" }, diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c index db4b5c5bdeb..537d3249338 100644 --- a/source/rpcclient/rpcclient.c +++ b/source/rpcclient/rpcclient.c @@ -25,20 +25,15 @@ extern int DEBUGLEVEL; extern fstring debugf; -/* Various pipe commands */ -extern struct cmd_set lsarpc_commands[]; -extern struct cmd_set samr_commands[]; -extern struct cmd_set spoolss_commands[]; +DOM_SID domain_sid; /* List to hold groups of commands */ + static struct cmd_list { struct cmd_list *prev, *next; struct cmd_set *cmd_set; } *cmd_list; - -DOM_SID domain_sid; - /**************************************************************************** handle completion of commands for readline ****************************************************************************/ @@ -160,9 +155,7 @@ static void read_authfile ( return; } -static char* next_command ( - char** cmdstr -) +static char* next_command (char** cmdstr) { static pstring command; char *p; @@ -201,22 +194,29 @@ void fetch_domain_sid(struct cli_state *cli) uint32 result = 0, info_class = 5; fstring domain_name; static BOOL got_domain_sid; + TALLOC_CTX *mem_ctx; if (got_domain_sid) return; + if (!(mem_ctx=talloc_init())) + { + DEBUG(0,("fetch_domain_sid: talloc_init returned NULL!\n")); + goto error; + } + if (!cli_nt_session_open (cli, PIPE_LSARPC)) { fprintf(stderr, "could not initialise lsa pipe\n"); goto error; } - if ((result = cli_lsa_open_policy(cli, True, + if ((result = cli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol) != NT_STATUS_NOPROBLEMO)) { goto error; } - if ((result = cli_lsa_query_info_policy(cli, &pol, info_class, + if ((result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, domain_name, &domain_sid)) != NT_STATUS_NOPROBLEMO) { goto error; @@ -224,8 +224,9 @@ void fetch_domain_sid(struct cli_state *cli) got_domain_sid = True; - cli_lsa_close(cli, &pol); + cli_lsa_close(cli, mem_ctx, &pol); cli_nt_session_close(cli); + talloc_destroy(mem_ctx); return; @@ -315,6 +316,24 @@ static struct cmd_set separator_command[] = { }; +/* Various pipe commands */ + +extern struct cmd_set lsarpc_commands[]; +extern struct cmd_set samr_commands[]; +extern struct cmd_set spoolss_commands[]; +extern struct cmd_set netlogon_commands[]; +extern struct cmd_set srvsvc_commands[]; + +static struct cmd_set *rpcclient_command_list[] = { + rpcclient_commands, + lsarpc_commands, + samr_commands, + spoolss_commands, + netlogon_commands, + srvsvc_commands, + NULL +}; + void add_command_set(struct cmd_set *cmd_set) { struct cmd_list *entry; @@ -399,11 +418,20 @@ static uint32 process_cmd(struct cli_state *cli, char *cmd) pstring buf; char *p = cmd; uint32 result=0; + int len = 0; + + if (cmd[strlen(cmd) - 1] == '\n') + cmd[strlen(cmd) - 1] = '\0'; if (!next_token(&p, buf, " ", sizeof(buf))) { return 0; } + /* strip the trainly \n if it exsists */ + len = strlen(buf); + if (buf[len-1] == '\n') + buf[len-1] = '\0'; + /* Search for matching commands */ for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) { @@ -508,6 +536,7 @@ static void usage(char *pname) username, domain, server; + struct cmd_set **cmd_set; charset_initialise(); setlinebuf(stdout); @@ -623,37 +652,33 @@ static void usage(char *pname) } /* There are no pointers in ntuser_creds struct so zero it out */ + ZERO_STRUCTP (&creds); - /* Load command lists */ - add_command_set(rpcclient_commands); - add_command_set(separator_command); - - add_command_set(spoolss_commands); - add_command_set(separator_command); - add_command_set(lsarpc_commands); - add_command_set(separator_command); - - add_command_set(samr_commands); - add_command_set(separator_command); - - - /* Do anything specified with -c */ - if (cmdstr[0]) { - char *cmd; - char *p = cmdstr; - - while((cmd=next_command(&p)) != NULL) { - process_cmd(&cli, cmd); - } + cmd_set = rpcclient_command_list; - return 0; + while(*cmd_set) { + add_command_set(*cmd_set); + add_command_set(separator_command); + cmd_set++; } + /* Do anything specified with -c */ + if (cmdstr[0]) { + char *cmd; + char *p = cmdstr; + + while((cmd=next_command(&p)) != NULL) { + process_cmd(&cli, cmd); + } + + return 0; + } /* Loop around accepting commands */ + while(1) { pstring prompt; char *line; @@ -662,7 +687,12 @@ static void usage(char *pname) line = smb_readline(prompt, NULL, completion_fn); - process_cmd(&cli, line); + if (line == NULL) + break; + + if (line[0] != '\n') + process_cmd(&cli, line); } -} + return 0; +} diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk index c66fe07972f..13ff399da0d 100644 --- a/source/script/mkproto.awk +++ b/source/script/mkproto.awk @@ -112,11 +112,11 @@ END { gotstart = 1; } - if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum nss_status|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) { + if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) { gotstart = 1; } - if( $0 ~ /^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) { + if( $0 ~ /^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) { gotstart = 1; } diff --git a/source/script/scancvslog.pl b/source/script/scancvslog.pl index 6e05c4c3d62..b1114f5706e 100755 --- a/source/script/scancvslog.pl +++ b/source/script/scancvslog.pl @@ -83,7 +83,7 @@ sub get_entry { $_ = <INFILE>; chomp $_; next if (not ($_)); - if (/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/) { + if (/^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/) { next if ($#Entry == -1); push(Entry,$_); return @Entry; diff --git a/source/script/uninstallcp.sh b/source/script/uninstallcp.sh index bd7013c358f..2a9e9d509ab 100755 --- a/source/script/uninstallcp.sh +++ b/source/script/uninstallcp.sh @@ -10,13 +10,13 @@ if [ ! -d $CPDIR ]; then fi for p in $*; do - if [ ! -f $CPDIR/codepage.$p ]; then - echo $CPDIR/codepage.$p does not exist! + if [ ! -f $CPDIR/unicode_map.$p ]; then + echo $CPDIR/unicode_map.$p does not exist! else - echo Removing $CPDIR/codepage.$p - rm -f $CPDIR/codepage.$p - if [ -f $CPDIR/codepage.$p ]; then - echo Cannot remove $CPDIR/codepage.$p... does $USER have privileges? + echo Removing $CPDIR/unicode_map.$p + rm -f $CPDIR/unicode_map.$p + if [ -f $CPDIR/unicode_map.$p ]; then + echo Cannot remove $CPDIR/unicode_map.$p... does $USER have privileges? fi fi done diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c index e8dc29f80ac..35d1e21f27f 100644 --- a/source/smbd/blocking.c +++ b/source/smbd/blocking.c @@ -130,10 +130,11 @@ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, static void send_blocking_reply(char *outbuf, int outsize) { - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); + if(outsize > 4) + smb_setlen(outbuf,outsize - 4); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_blocking_reply: send_smb failed.\n"); } /**************************************************************************** @@ -171,15 +172,16 @@ static void reply_lockingX_success(blocking_lock_record *blr) static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, int32 ecode) { - char *outbuf = OutBuffer; - char *inbuf = blr->inbuf; - construct_reply_common(inbuf, outbuf); + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + construct_reply_common(inbuf, outbuf); - if(eclass == 0) /* NT Error. */ - SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); + if(eclass == 0) /* NT Error. */ + SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - ERROR(eclass,ecode); - send_smb(smbd_server_fd(),outbuf); + ERROR(eclass,ecode); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("generic_blocking_lock_error: send_smb failed.\n"); } /**************************************************************************** @@ -194,6 +196,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; + uint16 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -217,6 +220,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec uint32 dummy2; BOOL err; + lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); @@ -225,7 +229,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec * request would never have been queued. JRA. */ - do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); + do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2); } generic_blocking_lock_error(blr, eclass, ecode); @@ -278,7 +282,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fsp, conn, (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { + if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* * We have other than a "can't get lock" POSIX @@ -341,7 +345,7 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL(inbuf,smb_vwv3); errno = 0; - if (!do_lock(fsp, conn, (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { + if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* @@ -390,6 +394,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; + uint16 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int eclass=0; @@ -405,6 +410,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { BOOL err; + lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); count = get_lock_count( data, blr->lock_num, large_file_format); offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); @@ -413,7 +419,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), + if(!do_lock(fsp,conn,count,lock_pid,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &eclass, &ecode)) break; } diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index 63f425f4cc3..083308d335f 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -20,9 +20,9 @@ */ /* fork a child process to exec passwd and write to its -* tty to change a users password. This is running as the -* user who is attempting to change the password. -*/ + * tty to change a users password. This is running as the + * user who is attempting to change the password. + */ /* * This code was copied/borrowed and stolen from various sources. @@ -456,47 +456,28 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root) /* Take the passed information and test it for minimum criteria */ /* Minimum password length */ - if (strlen(newpass) < lp_min_passwd_length()) /* too short, must be at least MINPASSWDLENGTH */ - { - DEBUG(0, - ("Password Change: user %s, New password is shorter than minimum password length = %d\n", + if (strlen(newpass) < lp_min_passwd_length()) { + /* too short, must be at least MINPASSWDLENGTH */ + DEBUG(0, ("Password Change: user %s, New password is shorter than minimum password length = %d\n", name, lp_min_passwd_length())); return (False); /* inform the user */ } /* Password is same as old password */ - if (strcmp(oldpass, newpass) == 0) /* don't allow same password */ - { - DEBUG(2, - ("Password Change: %s, New password is same as old\n", name)); /* log the attempt */ + if (strcmp(oldpass, newpass) == 0) { + /* don't allow same password */ + DEBUG(2, ("Password Change: %s, New password is same as old\n", name)); /* log the attempt */ return (False); /* inform the user */ } - pstrcpy(passwordprogram, lp_passwd_program()); - pstrcpy(chatsequence, lp_passwd_chat()); - - if (!*chatsequence) - { - DEBUG(2, ("Null chat sequence - no password changing\n")); - return (False); - } - - if (!*passwordprogram) - { - DEBUG(2, ("Null password program - no password changing\n")); - return (False); - } - /* * Check the old and new passwords don't contain any control * characters. */ len = strlen(oldpass); - for (i = 0; i < len; i++) - { - if (iscntrl((int)oldpass[i])) - { + for (i = 0; i < len; i++) { + if (iscntrl((int)oldpass[i])) { DEBUG(0, ("chat_with_program: oldpass contains control characters (disallowed).\n")); return False; @@ -504,16 +485,43 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root) } len = strlen(newpass); - for (i = 0; i < len; i++) - { - if (iscntrl((int)newpass[i])) - { + for (i = 0; i < len; i++) { + if (iscntrl((int)newpass[i])) { DEBUG(0, ("chat_with_program: newpass contains control characters (disallowed).\n")); return False; } } +#ifdef WITH_PAM + if (lp_pam_password_change()) { + BOOL ret; + + if (as_root) + become_root(); + + ret = smb_pam_passchange(name, oldpass, newpass); + + if (as_root) + unbecome_root(); + + return ret; + } +#endif + + pstrcpy(passwordprogram, lp_passwd_program()); + pstrcpy(chatsequence, lp_passwd_chat()); + + if (!*chatsequence) { + DEBUG(2, ("Null chat sequence - no password changing\n")); + return (False); + } + + if (!*passwordprogram) { + DEBUG(2, ("Null password program - no password changing\n")); + return (False); + } + pstring_sub(passwordprogram, "%u", name); /* note that we do NOT substitute the %o and %n in the password program as this would open up a security hole where the user could use @@ -527,6 +535,7 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root) } #else /* ALLOW_CHANGE_PASSWORD */ + BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root) { DEBUG(0, ("Password changing not compiled in (user=%s)\n", name)); @@ -770,7 +779,7 @@ BOOL check_oem_password(char *user, /* * Call the hash function to get the new password. */ - SamOEMhash((uchar *) lmdata, (uchar *) smbpw->smb_passwd, True); + SamOEMhash((uchar *) lmdata, (uchar *) smbpw->smb_passwd, 516); /* * The length of the new password is in the last 4 bytes of diff --git a/source/smbd/conn.c b/source/smbd/conn.c index e160c6ac83d..725ab22dc44 100644 --- a/source/smbd/conn.c +++ b/source/smbd/conn.c @@ -198,3 +198,33 @@ void conn_free(connection_struct *conn) ZERO_STRUCTP(conn); free(conn); } + + +/**************************************************************************** +receive a smbcontrol message to forcibly unmount a share +the message contains just a share name and all instances of that +share are unmounted +the special sharename '*' forces unmount of all shares +****************************************************************************/ +void msg_force_tdis(int msg_type, pid_t pid, void *buf, size_t len) +{ + connection_struct *conn, *next; + fstring sharename; + + fstrcpy(sharename, buf); + + if (strcmp(sharename, "*") == 0) { + DEBUG(1,("Forcing close of all shares\n")); + conn_close_all(); + return; + } + + for (conn=Connections;conn;conn=next) { + next=conn->next; + if (strequal(lp_servicename(conn->service), sharename)) { + DEBUG(1,("Forcing close of share %s cnum=%d\n", + sharename, conn->cnum)); + close_cnum(conn, (uint16)-1); + } + } +} diff --git a/source/smbd/connection.c b/source/smbd/connection.c index 4039c08da9f..796a54e77dd 100644 --- a/source/smbd/connection.c +++ b/source/smbd/connection.c @@ -27,11 +27,6 @@ static TDB_CONTEXT *tdb; extern int DEBUGLEVEL; -#ifdef WITH_UTMP -static void utmp_yield(pid_t pid, const connection_struct *conn); -static void utmp_claim(const struct connections_data *crec, const connection_struct *conn); -#endif - /**************************************************************************** Return the connection tdb context (used for message send all). ****************************************************************************/ @@ -42,8 +37,9 @@ TDB_CONTEXT *conn_tdb_ctx(void) } /**************************************************************************** -delete a connection record + Delete a connection record. ****************************************************************************/ + BOOL yield_connection(connection_struct *conn,char *name,int max_connections) { struct connections_key key; @@ -62,827 +58,156 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections) kbuf.dptr = (char *)&key; kbuf.dsize = sizeof(key); - tdb_delete(tdb, kbuf); - -#ifdef WITH_UTMP - if(conn) - utmp_yield(key.pid, conn); -#endif - - return(True); -} - - -/**************************************************************************** -claim an entry in the connections database -****************************************************************************/ -BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear) -{ - struct connections_key key; - struct connections_data crec; - TDB_DATA kbuf, dbuf; - - if (!tdb) { - tdb = tdb_open(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT, 0644); + if (tdb_delete(tdb, kbuf) != 0) { + DEBUG(0,("yield_connection: tdb_delete failed with error %s.\n", tdb_errorstr(tdb) )); + return (False); } - if (!tdb) return False; - - DEBUG(5,("claiming %s %d\n",name,max_connections)); - - ZERO_STRUCT(key); - key.pid = sys_getpid(); - key.cnum = conn?conn->cnum:-1; - fstrcpy(key.name, name); - dos_to_unix(key.name, True); /* Convert key to unix-codepage */ - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); - - /* fill in the crec */ - ZERO_STRUCT(crec); - crec.magic = 0x280267; - crec.pid = sys_getpid(); - crec.cnum = conn?conn->cnum:-1; - if (conn) { - crec.uid = conn->uid; - crec.gid = conn->gid; - StrnCpy(crec.name, - lp_servicename(SNUM(conn)),sizeof(crec.name)-1); - } - crec.start = time(NULL); - - StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1); - StrnCpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1); - - dbuf.dptr = (char *)&crec; - dbuf.dsize = sizeof(crec); - - if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) return False; - -#ifdef WITH_UTMP - if (conn) - utmp_claim(&crec, conn); -#endif - - return True; + return(True); } -#ifdef WITH_UTMP - -/**************************************************************************** -Reflect connection status in utmp/wtmp files. - T.D.Lee@durham.ac.uk September 1999 - - With grateful thanks since then to many who have helped port it to - different operating systems. The variety of OS quirks thereby - uncovered is amazing... - -Hints for porting: - o Always attempt to use programmatic interface (pututline() etc.) - Indeed, at present only programmatic use is supported. - o The only currently supported programmatic interface to "wtmp{,x}" - is through "updwtmp*()" routines. - o The "x" (utmpx/wtmpx; HAVE_UTMPX_H) seems preferable. - o The HAVE_* items should identify supported features. - o If at all possible, avoid "if defined(MY-OS)" constructions. - -OS observations and status: - Almost every OS seems to have its own quirks. - - Solaris 2.x: - Tested on 2.6 and 2.7; should be OK on other flavours. - AIX: - Apparently has utmpx.h but doesn't implement. - OSF: - Has utmpx.h, but (e.g.) no "getutmpx()". (Is this like AIX ?) - Redhat 6: - utmpx.h seems not to set default filenames. non-x better. - IRIX 6.5: - Not tested. Appears to have "x". - HP-UX 9.x: - Not tested. Appears to lack "x". - HP-UX 10.x: - Not tested. - "updwtmp*()" routines seem absent, so no current wtmp* support. - Has "ut_addr": probably trivial to implement (although remember - that IPv6 is coming...). - - FreeBSD: - No "putut*()" type of interface. - No "ut_type" and associated defines. - Write files directly. Alternatively use its login(3)/logout(3). - SunOS 4: - Not tested. Resembles FreeBSD, but no login()/logout(). - -lastlog: - Should "lastlog" files, if any, be updated? - BSD systems (SunOS 4, FreeBSD): - o Prominent mention on man pages. - System-V (e.g. Solaris 2): - o No mention on man pages, even under "man -k". - o Has a "/var/adm/lastlog" file, but pututxline() etc. seem - not to touch it. - o Despite downplaying (above), nevertheless has <lastlog.h>. - So perhaps UN*X "lastlog" facility is intended for tty/terminal only? - -Notes: - Each connection requires a small number (starting at 0, working up) - to represent the line (unum). This must be unique within and across - all smbd processes. - - The 4 byte 'ut_id' component is vital to distinguish connections, - of which there could be several hundered or even thousand. - Entries seem to be printable characters, with optional NULL pads. - - We need to be distinct from other entries in utmp/wtmp. - - Observed things: therefore avoid them. Add to this list please. - From Solaris 2.x (because that's what I have): - 'sN' : run-levels; N: [0-9] - 'co' : console - 'CC' : arbitrary things; C: [a-z] - 'rXNN' : rlogin; N: [0-9]; X: [0-9a-z] - 'tXNN' : rlogin; N: [0-9]; X: [0-9a-z] - '/NNN' : Solaris CDE - 'ftpZ' : ftp (Z is the number 255, aka 0377, aka 0xff) - Mostly a record uses the same 'ut_id' in both "utmp" and "wtmp", - but differences have been seen. - - Arbitrarily I have chosen to use a distinctive 'SM' for the - first two bytes. - - The remaining two encode the "unum" (see above). - - For "utmp consolidate" the suggestion was made to encode the pid into - those remaining two bytes (16 bits). But recent UNIX (e.g Solaris 8) - is migrating to pids > 16 bits, so we ought not to do this. - -****************************************************************************/ - -#include <utmp.h> - -#ifdef HAVE_UTMPX_H -#include <utmpx.h> -#endif - -/* BSD systems: some may need lastlog.h (SunOS 4), some may not (FreeBSD) */ -/* Some System-V systems (e.g. Solaris 2) declare this too. */ -#ifdef HAVE_LASTLOG_H -#include <lastlog.h> -#endif +struct count_stat { + pid_t mypid; + int curr_connections; + char *name; + BOOL Clear; +}; /**************************************************************************** -obtain/release a small number (0 upwards) unique within and across smbds + Count the entries belonging to a service in the connection db. ****************************************************************************/ -/* - * Need a "small" number to represent this connection, unique within this - * smbd and across all smbds. - * - * claim: - * Start at 0, hunt up for free, unique number "unum" by attempting to - * store it as a key in a tdb database: - * key: unum data: pid+conn - * Also store its inverse, ready for yield function: - * key: pid+conn data: unum - * - * yield: - * Find key: pid+conn; data is unum; delete record - * Find key: unum ; delete record. - * - * Comment: - * The claim algorithm (a "for" loop attempting to store numbers in a tdb - * database) will be increasingly inefficient with larger numbers of - * connections. Is it possible to write a suitable primitive within tdb? - * - * However, by also storing the inverse key/data pair, we at least make - * the yield algorithm efficient. - */ - -static TDB_CONTEXT *tdb_utmp; - -struct utmp_tdb_data { - pid_t pid; - int cnum; -}; - -static int utmp_claim_tdb(const connection_struct *conn) -{ - struct utmp_tdb_data udata; - int i, slotnum; - TDB_DATA kbuf, dbuf; - - if (!tdb_utmp) { - tdb_utmp = tdb_open(lock_path("utmp.tdb"), 0, - TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644); - } - if (!tdb_utmp) return(-1); - - DEBUG(2,("utmp_claim_tdb: entered\n")); - - ZERO_STRUCT(udata); - udata.pid = sys_getpid(); - udata.cnum = conn ? conn->cnum : -1; - - dbuf.dptr = (char *) &udata; - dbuf.dsize = sizeof(udata); - - /* The key is simply a number as close as possible to zero: find it */ - slotnum = -1; - /* stop loop when overflow +ve integers (a huge, busy machine!) */ - for (i = 0; i >= 0 ; i++) { - kbuf.dptr = (char *) &i; - kbuf.dsize = sizeof(i); - - if (tdb_store(tdb_utmp, kbuf, dbuf, TDB_INSERT) == 0) { - /* have successfully grabbed a free slot */ - slotnum = i; - - /* store the inverse for faster utmp_yield_tdb() */ - tdb_store(tdb_utmp, dbuf, kbuf, TDB_INSERT); - - break; /* Got it; escape */ - } - } - if (slotnum < 0) { /* more connections than positive integers! */ - DEBUG(2,("utmp_claim_tdb: failed\n")); - return(-1); - } - - DEBUG(2,("utmp_claim_tdb: leaving with %d\n", slotnum)); - - return(slotnum); -} -static int utmp_yield_tdb(const connection_struct *conn) +static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *udp) { - struct utmp_tdb_data revkey; - int i, slotnum; - TDB_DATA kbuf, dbuf; - - if (!tdb_utmp) { - return(-1); - } - - DEBUG(2,("utmp_yield_tdb: entered\n")); + struct connections_data crec; + struct count_stat *cs = (struct count_stat *)udp; + + if (dbuf.dsize != sizeof(crec)) + return 0; - ZERO_STRUCT(revkey); - revkey.pid = sys_getpid(); - revkey.cnum = conn ? conn->cnum : -1; + memcpy(&crec, dbuf.dptr, sizeof(crec)); + + if (crec.cnum == -1) + return 0; - kbuf.dptr = (char *) &revkey; - kbuf.dsize = sizeof(revkey); + /* If the pid was not found delete the entry from connections.tdb */ - dbuf = tdb_fetch(tdb_utmp, kbuf); - if (dbuf.dptr == NULL) { - DEBUG(2,("utmp_yield_tdb: failed\n")); - return(-1); /* shouldn't happen */ + if (cs->Clear && !process_exists(crec.pid) && (errno == ESRCH)) { + DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n", + (unsigned int)crec.pid, crec.cnum, crec.name)); + if (tdb_delete(the_tdb, kbuf) != 0) + DEBUG(0,("count_fn: tdb_delete failed with error %s\n", tdb_errorstr(tdb) )); + return 0; } - /* Save our result */ - slotnum = *((int*) dbuf.dptr); - - /* Tidy up */ - tdb_delete(tdb_utmp, kbuf); - tdb_delete(tdb_utmp, dbuf); - - free(dbuf.dptr); - DEBUG(2,("utmp_yield_tdb: leaving with %d\n", slotnum)); + if (strequal(crec.name, cs->name)) + cs->curr_connections++; - return(slotnum); + return 0; } -#if defined(HAVE_UT_UT_ID) /**************************************************************************** -encode the unique connection number into "ut_id" + Claim an entry in the connections database. ****************************************************************************/ -static const char *ut_id_encstr = - "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -static -int -ut_id_encode(int i, char *fourbyte) -{ - int nbase; - - fourbyte[0] = 'S'; - fourbyte[1] = 'M'; - -/* - * Encode remaining 2 bytes from 'i'. - * 'ut_id_encstr' is the character set on which modulo arithmetic is done. - * Example: digits would produce the base-10 numbers from '001'. - */ - nbase = strlen(ut_id_encstr); - - fourbyte[3] = ut_id_encstr[i % nbase]; - i /= nbase; - fourbyte[2] = ut_id_encstr[i % nbase]; - i /= nbase; - - return(i); /* 0: good; else overflow */ -} -#endif /* defined(HAVE_UT_UT_ID) */ - -/* - * ut_line: - * size small, e.g. Solaris: 12; FreeBSD: 8 - * pattern conventions differ across systems. - * So take care in tweaking the template below. - * Arguably, this could be yet another smb.conf parameter. - */ -static const char *ut_line_template = -#if defined(__FreeBSD__) - "smb%d" ; -#else - "smb/%d" ; -#endif - -/**************************************************************************** -Fill in a utmp (not utmpx) template -****************************************************************************/ -static int utmp_fill(struct utmp *u, const connection_struct *conn, pid_t pid, - int i, pstring host) +BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear) { -#if defined(HAVE_UT_UT_TIME) - struct timeval timeval; -#endif /* defined(HAVE_UT_UT_TIME) */ - char line_tmp[1024]; /* plenty big enough for slprintf() */ - int line_len; - int rc = 0; - -/* - * ut_name, ut_user: - * Several (all?) systems seems to define one as the other. - * It is easier and clearer simply to let the following take its course, - * rather than to try to detect and optimise. - */ -#if defined(HAVE_UT_UT_USER) - pstrcpy(u->ut_user, conn->user); -#endif /* defined(HAVE_UT_UT_USER) */ - -#if defined(HAVE_UT_UT_NAME) - pstrcpy(u->ut_name, conn->user); -#endif /* defined(HAVE_UT_UT_NAME) */ - -/* - * ut_line: - * If size limit proves troublesome, then perhaps use "ut_id_encode()". - * - * Temporary variable "line_tmp" avoids trouble: - * o with unwanted trailing NULL if ut_line full; - * o with overflow if ut_line would be more than full. - */ - memset(line_tmp, '\0', sizeof(line_tmp)); - slprintf(line_tmp, sizeof(line_tmp)-1, (char *) ut_line_template, i); - line_len = strlen(line_tmp); - if (line_len <= sizeof(u->ut_line)) { - memcpy(u->ut_line, line_tmp, sizeof(u->ut_line)); - } - else { - DEBUG(1,("utmp_fill: ut_line exceeds field length(%d > %d)\n", - line_len, sizeof(u->ut_line))); - return(1); - } + struct connections_key key; + struct connections_data crec; + TDB_DATA kbuf, dbuf, lockkey; + BOOL rec_locked = False; + BOOL ret = True; -#if defined(HAVE_UT_UT_PID) - u->ut_pid = pid; -#endif /* defined(HAVE_UT_UT_PID) */ - -/* - * ut_time, ut_tv: - * Some have one, some the other. Many have both, but defined (aliased). - * It is easier and clearer simply to let the following take its course. - * But note that we do the more precise ut_tv as the final assignment. - */ -#if defined(HAVE_UT_UT_TIME) - gettimeofday(&timeval, NULL); - u->ut_time = timeval.tv_sec; -#endif /* defined(HAVE_UT_UT_TIME) */ - -#if defined(HAVE_UT_UT_TV) - gettimeofday(&timeval, NULL); - u->ut_tv = timeval; -#endif /* defined(HAVE_UT_UT_TV) */ - -#if defined(HAVE_UT_UT_HOST) - if (host) { - pstrcpy(u->ut_host, host); + if (!tdb) { + tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT, 0644); } -#endif /* defined(HAVE_UT_UT_HOST) */ + if (!tdb) + return False; -#if defined(HAVE_UT_UT_ADDR) /* - * "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20. - * Volunteer to implement, please ... - */ -#endif /* defined(HAVE_UT_UT_ADDR) */ - -#if defined(HAVE_UT_UT_ID) - rc = ut_id_encode(i, u->ut_id); -#endif /* defined(HAVE_UT_UT_ID) */ - - return(rc); -} - -/**************************************************************************** -Default paths to various {u,w}tmp{,x} files -****************************************************************************/ -#ifdef HAVE_UTMPX_H - -static const char *ux_pathname = -# if defined (UTMPX_FILE) - UTMPX_FILE ; -# elif defined (_UTMPX_FILE) - _UTMPX_FILE ; -# elif defined (_PATH_UTMPX) - _PATH_UTMPX ; -# else - "" ; -# endif - -static const char *wx_pathname = -# if defined (WTMPX_FILE) - WTMPX_FILE ; -# elif defined (_WTMPX_FILE) - _WTMPX_FILE ; -# elif defined (_PATH_WTMPX) - _PATH_WTMPX ; -# else - "" ; -# endif - -#endif /* HAVE_UTMPX_H */ - -static const char *ut_pathname = -# if defined (UTMP_FILE) - UTMP_FILE ; -# elif defined (_UTMP_FILE) - _UTMP_FILE ; -# elif defined (_PATH_UTMP) - _PATH_UTMP ; -# else - "" ; -# endif - -static const char *wt_pathname = -# if defined (WTMP_FILE) - WTMP_FILE ; -# elif defined (_WTMP_FILE) - _WTMP_FILE ; -# elif defined (_PATH_WTMP) - _PATH_WTMP ; -# else - "" ; -# endif - -/* BSD-like systems might want "lastlog" support. */ -/* *** Not yet implemented */ -#ifndef HAVE_PUTUTLINE /* see "pututline_my()" */ -static const char *ll_pathname = -# if defined (_PATH_LASTLOG) /* what other names (if any?) */ - _PATH_LASTLOG ; -# else - "" ; -# endif /* _PATH_LASTLOG */ -#endif /* HAVE_PUTUTLINE */ - -/* - * Get name of {u,w}tmp{,x} file. - * return: fname contains filename - * Possibly empty if this code not yet ported to this system. - * - * utmp{,x}: try "utmp dir", then default (a define) - * wtmp{,x}: try "wtmp dir", then "utmp dir", then default (a define) - */ -static void uw_pathname(pstring fname, const char *uw_name, const char *uw_default) -{ - pstring dirname; - - pstrcpy(dirname, ""); - - /* For w-files, first look for explicit "wtmp dir" */ - if (uw_name[0] == 'w') { - pstrcpy(dirname,lp_wtmpdir()); - trim_string(dirname,"","/"); - } - - /* For u-files and non-explicit w-dir, look for "utmp dir" */ - if (dirname == 0 || strlen(dirname) == 0) { - pstrcpy(dirname,lp_utmpdir()); - trim_string(dirname,"","/"); - } - - /* If explicit directory above, use it */ - if (dirname != 0 && strlen(dirname) != 0) { - pstrcpy(fname, dirname); - pstrcat(fname, "/"); - pstrcat(fname, uw_name); - return; - } - - /* No explicit directory: attempt to use default paths */ - if (strlen(uw_default) == 0) { - /* No explicit setting, no known default. - * Has it yet been ported to this OS? - */ - DEBUG(2,("uw_pathname: unable to determine pathname\n")); - } - pstrcpy(fname, uw_default); -} - -#ifndef HAVE_PUTUTLINE -/**************************************************************************** -Update utmp file directly. No subroutine interface: probably a BSD system. -****************************************************************************/ -static void pututline_my(pstring uname, struct utmp *u, BOOL claim) -{ - DEBUG(1,("pututline_my: not yet implemented\n")); - /* BSD implementor: may want to consider (or not) adjusting "lastlog" */ -} -#endif /* HAVE_PUTUTLINE */ - -#ifndef HAVE_UPDWTMP -/**************************************************************************** -Update wtmp file directly. No subroutine interface: probably a BSD system. -Credit: Michail Vidiassov <master@iaas.msu.ru> -****************************************************************************/ -static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim) -{ - int fd; - struct stat buf; - - if (! claim) { - /* - * BSD-like systems: - * may use empty ut_name to distinguish a logout record. - * - * May need "if defined(SUNOS4)" etc. around some of these, - * but try to avoid if possible. - * - * SunOS 4: - * man page indicates ut_name and ut_host both NULL - * FreeBSD 4.0: - * man page appears not to specify (hints non-NULL) - * A correspondent suggest at least ut_name should be NULL - */ - memset((char *)&(u->ut_name), '\0', sizeof(u->ut_name)); - memset((char *)&(u->ut_host), '\0', sizeof(u->ut_host)); - } - /* Stolen from logwtmp function in libutil. - * May be more locking/blocking is needed? + * Enforce the max connections parameter. */ - if ((fd = open(wname, O_WRONLY|O_APPEND, 0)) < 0) - return; - if (fstat(fd, &buf) == 0) { - if (write(fd, (char *)u, sizeof(struct utmp)) != sizeof(struct utmp)) - (void) ftruncate(fd, buf.st_size); - } - (void) close(fd); -} -#endif /* HAVE_UPDWTMP */ -/**************************************************************************** -Update via utmp/wtmp (not utmpx/wtmpx) -****************************************************************************/ -static void utmp_nox_update(struct utmp *u, pstring host, BOOL claim) -{ - pstring uname, wname; -#if defined(PUTUTLINE_RETURNS_UTMP) - struct utmp *urc; -#endif /* PUTUTLINE_RETURNS_UTMP */ - - uw_pathname(uname, "utmp", ut_pathname); - DEBUG(2,("utmp_nox_update: uname:%s\n", uname)); + if (max_connections > 0) { + struct count_stat cs; -#ifdef HAVE_PUTUTLINE - if (strlen(uname) != 0) { - utmpname(uname); - } + cs.mypid = sys_getpid(); + cs.curr_connections = 0; + cs.name = lp_servicename(SNUM(conn)); + cs.Clear = Clear; -# if defined(PUTUTLINE_RETURNS_UTMP) - setutent(); - urc = pututline(u); - endutent(); - if (urc == NULL) { - DEBUG(2,("utmp_nox_update: pututline() failed\n")); - return; - } -# else /* PUTUTLINE_RETURNS_UTMP */ - setutent(); - pututline(u); - endutent(); -# endif /* PUTUTLINE_RETURNS_UTMP */ - -#else /* HAVE_PUTUTLINE */ - if (strlen(uname) != 0) { - pututline_my(uname, u, claim); - } -#endif /* HAVE_PUTUTLINE */ + lockkey.dptr = cs.name; + lockkey.dsize = strlen(cs.name)+1; - uw_pathname(wname, "wtmp", wt_pathname); - DEBUG(2,("utmp_nox_update: wname:%s\n", wname)); - if (strlen(wname) != 0) { -#ifdef HAVE_UPDWTMP - updwtmp(wname, u); /* - * updwtmp() and the newer updwtmpx() may be unsymmetrical. - * At least one OS, Solaris 2.x declares the former in the - * "utmpx" (latter) file and context. - * In the Solaris case this is irrelevant: it has both and - * we always prefer the "x" case, so doesn't come here. - * But are there other systems, with no "x", which lack - * updwtmp() perhaps? + * Go through and count the connections with hash chain representing the service name + * locked. This is slow but removes race conditions. JRA. */ -#else - updwtmp_my(wname, u, claim); -#endif /* HAVE_UPDWTMP */ - } -} - -/**************************************************************************** -Update via utmpx/wtmpx (preferred) or via utmp/wtmp -****************************************************************************/ -static void utmp_update(struct utmp *u, pstring host, BOOL claim) -{ -#if !defined(HAVE_UTMPX_H) - /* No utmpx stuff. Drop to non-x stuff */ - utmp_nox_update(u, host, claim); -#elif !defined(HAVE_PUTUTXLINE) - /* Odd. Have utmpx.h but no "pututxline()". Drop to non-x stuff */ - DEBUG(1,("utmp_update: have utmpx.h but no pututxline() function\n")); - utmp_nox_update(u, host, claim); -#elif !defined(HAVE_GETUTMPX) - /* Odd. Have utmpx.h but no "getutmpx()". Drop to non-x stuff */ - DEBUG(1,("utmp_update: have utmpx.h but no getutmpx() function\n")); - utmp_nox_update(u, host, claim); -#else - pstring uname, wname; - struct utmpx ux, *uxrc; - - getutmpx(u, &ux); - if (host) { -#if defined(HAVE_UX_UT_SYSLEN) - ux.ut_syslen = strlen(host) + 1; /* include end NULL */ -#endif /* defined(HAVE_UX_UT_SYSLEN) */ - pstrcpy(ux.ut_host, host); - } - uw_pathname(uname, "utmpx", ux_pathname); - uw_pathname(wname, "wtmpx", wx_pathname); - DEBUG(2,("utmp_update: uname:%s wname:%s\n", uname, wname)); - /* - * Check for either uname or wname being empty. - * Some systems, such as Redhat 6, have a "utmpx.h" which doesn't - * define default filenames. - * Also, our local installation has not provided an override. - * Drop to non-x method. (E.g. RH6 has good defaults in "utmp.h".) - */ - if ((strlen(uname) == 0) || (strlen(wname) == 0)) { - utmp_nox_update(u, host, claim); - } - else { - utmpxname(uname); - setutxent(); - uxrc = pututxline(&ux); - endutxent(); - if (uxrc == NULL) { - DEBUG(2,("utmp_update: pututxline() failed\n")); - return; + if (tdb_chainlock(tdb, lockkey)) { + DEBUG(0,("claim_connection: tdb_chainlock failed %s\n", + tdb_errorstr(tdb) )); + return False; } -#ifdef HAVE_UPDWTMPX - updwtmpx(wname, &ux); -#else - /* Have utmpx.h but no "updwtmpx()". */ - DEBUG(1,("utmp_update: no updwtmpx() function\n")); -#endif /* HAVE_UPDWTMPX */ - } -#endif /* HAVE_UTMPX_H */ -} -/* - * "utmp consolidate": some background: - * False (default): - * In "utmp" files note every connection via this process. - * Argument "i" is simply a tty-like number we can use as-is. - * True: - * In "utmp" files, only note first open and final close. Keep: - * o count of open processes; - * o record value of first "i", to use as "i" in final close. - */ -static int utmp_count = 0; -static int utmp_consolidate_conn_num; + rec_locked = True; -/**************************************************************************** -close a connection -****************************************************************************/ -static void utmp_yield(pid_t pid, const connection_struct *conn) -{ - struct utmp u; - int conn_num, i; - - if (! lp_utmp(SNUM(conn))) { - DEBUG(2,("utmp_yield: lp_utmp() NULL\n")); - return; - } - - i = utmp_yield_tdb(conn); - if (i < 0) { - DEBUG(2,("utmp_yield: utmp_yield_tdb() failed\n")); - return; - } - conn_num = i; - DEBUG(2,("utmp_yield: conn: user:%s cnum:%d i:%d (utmp_count:%d)\n", - conn->user, conn->cnum, i, utmp_count)); - - utmp_count -= 1; - if (lp_utmp_consolidate()) { - if (utmp_count > 0) { - DEBUG(2,("utmp_yield: utmp consolidate: %d entries still open\n", utmp_count)); - return; + if (tdb_traverse(tdb, count_fn, &cs) == -1) { + DEBUG(0,("claim_connection: traverse of connections.tdb failed with error %s.\n", + tdb_errorstr(tdb) )); + ret = False; + goto out; } - else { - /* consolidate; final close: override conn_num */ - conn_num = utmp_consolidate_conn_num; + + if (cs.curr_connections >= max_connections) { + DEBUG(1,("claim_connection: Max connections (%d) exceeded for %s\n", + max_connections, name )); + ret = False; + goto out; } } - memset((char *)&u, '\0', sizeof(struct utmp)); - -#if defined(HAVE_UT_UT_EXIT) - u.ut_exit.e_termination = 0; - u.ut_exit.e_exit = 0; -#endif /* defined(HAVE_UT_UT_EXIT) */ - -#if defined(HAVE_UT_UT_TYPE) - u.ut_type = DEAD_PROCESS; -#endif /* defined(HAVE_UT_UT_TYPE) */ - - if (utmp_fill(&u, conn, pid, conn_num, NULL) == 0) { - utmp_update(&u, NULL, False); - } -} - -/**************************************************************************** -open a connection -****************************************************************************/ -static void utmp_claim(const struct connections_data *crec, const connection_struct *conn) -{ - struct utmp u; - pstring host; - int i; - - if (conn == NULL) { - DEBUG(2,("utmp_claim: conn NULL\n")); - return; - } + DEBUG(5,("claiming %s %d\n",name,max_connections)); - if (! lp_utmp(SNUM(conn))) { - DEBUG(2,("utmp_claim: lp_utmp() NULL\n")); - return; - } + ZERO_STRUCT(key); + key.pid = sys_getpid(); + key.cnum = conn?conn->cnum:-1; + fstrcpy(key.name, name); + dos_to_unix(key.name, True); /* Convert key to unix-codepage */ - i = utmp_claim_tdb(conn); - if (i < 0) { - DEBUG(2,("utmp_claim: utmp_claim_tdb() failed\n")); - return; - } + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); - pstrcpy(host, lp_utmp_hostname()); - if (host == 0 || strlen(host) == 0) { - pstrcpy(host, crec->machine); - } - else { - /* explicit "utmp host": expand for any "%" variables */ - standard_sub_basic(host); + /* fill in the crec */ + ZERO_STRUCT(crec); + crec.magic = 0x280267; + crec.pid = sys_getpid(); + crec.cnum = conn?conn->cnum:-1; + if (conn) { + crec.uid = conn->uid; + crec.gid = conn->gid; + StrnCpy(crec.name, + lp_servicename(SNUM(conn)),sizeof(crec.name)-1); } + crec.start = time(NULL); + + StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1); + StrnCpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1); - DEBUG(2,("utmp_claim: conn: user:%s cnum:%d i:%d (utmp_count:%d)\n", - conn->user, conn->cnum, i, utmp_count)); - DEBUG(2,("utmp_claim: crec: pid:%d, cnum:%d name:%s addr:%s mach:%s DNS:%s host:%s\n", - crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_name(), host)); + dbuf.dptr = (char *)&crec; + dbuf.dsize = sizeof(crec); - utmp_count += 1; - if (lp_utmp_consolidate()) { - if (utmp_count > 1) { - DEBUG(2,("utmp_claim: utmp consolidate: %d entries already open\n", (utmp_count-1))); - return; - } - else { - /* consolidate; first open: keep record of "i" */ - utmp_consolidate_conn_num = i; - } + if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + DEBUG(0,("claim_connection: tdb_store failed with error %s.\n", + tdb_errorstr(tdb) )); + ret = False; } - memset((char *)&u, '\0', sizeof(struct utmp)); + out: -#if defined(HAVE_UT_UT_TYPE) - u.ut_type = USER_PROCESS; -#endif /* defined(HAVE_UT_UT_TYPE) */ + if (rec_locked) + tdb_chainunlock(tdb, lockkey); - if (utmp_fill(&u, conn, crec->pid, i, host) == 0) { - utmp_update(&u, host, True); - } + return ret; } - -#endif /* WITH_UTMP */ diff --git a/source/smbd/dir.c b/source/smbd/dir.c index 5bf0dec9444..fa9cbdc4a2a 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -663,6 +663,36 @@ typedef struct } Dir; + +/******************************************************************* +check to see if a user can read a file. This is only approximate, +it is used as part of the "hide unreadable" option. Don't +use it for anything security sensitive +********************************************************************/ +static BOOL user_can_read_file(connection_struct *conn, char *name) +{ + SMB_STRUCT_STAT ste; + + /* if we can't stat it does not show it */ + if (vfs_stat(conn, name, &ste) != 0) return False; + + if (ste.st_uid == conn->uid) { + return (ste.st_mode & S_IRUSR) == S_IRUSR; + } else { + int i; + if (ste.st_gid == conn->gid) { + return (ste.st_mode & S_IRGRP) == S_IRGRP; + } + for (i=0; i<conn->ngroups; i++) { + if (conn->groups[i] == ste.st_gid) { + return (ste.st_mode & S_IRGRP) == S_IRGRP; + } + } + } + + return (ste.st_mode & S_IROTH) == S_IROTH; +} + /******************************************************************* Open a directory. ********************************************************************/ @@ -677,6 +707,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) if (!p) return(NULL); dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { + DEBUG(0,("Out of memory in OpenDir\n")); conn->vfs_ops.closedir(conn,p); return(NULL); } @@ -695,6 +726,18 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) /* If it's a vetoed file, pretend it doesn't even exist */ if (use_veto && conn && IS_VETO_PATH(conn, n)) continue; + /* Honour _hide unreadable_ option */ + if (conn && lp_hideunreadable(SNUM(conn))) { + char *entry; + int ret=0; + + if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = user_can_read_file(conn, entry); + free(entry); + } + if (!ret) continue; + } + if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 6fd4951769f..76b043c2dac 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -103,12 +103,12 @@ void send_trans_reply(char *outbuf, if (buffer_too_large) { /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */ - if (!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) { + if (!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) { /* Win9x version. */ SSVAL(outbuf, smb_err, ERRmoredata); SCVAL(outbuf, smb_rcls, ERRDOS); } else { - SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); + SIVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); SIVAL(outbuf, smb_rcls, 0x80000000 | STATUS_BUFFER_OVERFLOW); } } @@ -128,7 +128,8 @@ void send_trans_reply(char *outbuf, SSVAL(outbuf,smb_vwv9,0); show_msg(outbuf); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_trans_reply: send_smb failed.\n"); tot_data_sent = this_ldata; tot_param_sent = this_lparam; @@ -161,7 +162,8 @@ void send_trans_reply(char *outbuf, SSVAL(outbuf,smb_vwv9,0); show_msg(outbuf); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_trans_reply: send_smb failed.\n"); tot_data_sent += this_ldata; tot_param_sent += this_lparam; @@ -424,7 +426,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); show_msg(outbuf); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("reply_trans: send_smb failed.\n"); } /* receive the rest of the trans packet */ @@ -489,10 +492,18 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int (name[strlen(local_machine)+1] == '\\')) name_offset = strlen(local_machine)+1; - if (strncmp(&name[name_offset],"\\PIPE\\",strlen("\\PIPE\\")) == 0) { + if (strnequal(&name[name_offset], "\\PIPE", strlen("\\PIPE"))) { + name_offset += strlen("\\PIPE"); + + /* Win9x weirdness. When talking to a unicode server Win9x + only sends \PIPE instead of \PIPE\ */ + + if (name[name_offset] == '\\') + name_offset++; + DEBUG(5,("calling named_pipe\n")); outsize = named_pipe(conn,vuid,outbuf, - name+name_offset+strlen("\\PIPE\\"),setup,data,params, + name+name_offset,setup,data,params, suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt); } else { DEBUG(3,("invalid pipe name\n")); diff --git a/source/smbd/message.c b/source/smbd/message.c index 59b8cf85869..b3da3f2b611 100644 --- a/source/smbd/message.c +++ b/source/smbd/message.c @@ -61,13 +61,12 @@ static void msg_deliver(void) } /* - * Incoming message is in DOS codepage format. Convert to UNIX in - * place. + * Incoming message is in DOS codepage format. Convert to UNIX. */ if(msgpos > 0) { msgbuf[msgpos] = '\0'; /* Ensure null terminated. */ - dos_to_unix(msgbuf,True); + pstrcpy(msgbuf,dos_to_unix(msgbuf,False)); } for (i=0;i<msgpos;) { diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c index 8ce9074d806..25419caf625 100644 --- a/source/smbd/negprot.c +++ b/source/smbd/negprot.c @@ -160,6 +160,8 @@ static int reply_nt1(char *outbuf) /* dual names + lock_and_read + nt SMBs + remote API calls */ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_LEVEL_II_OPLOCKS| (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) | + ((lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) ? + CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS : 0) | (SMB_OFF_T_BITS == 64 ? CAP_LARGE_FILES : 0); diff --git a/source/smbd/notify.c b/source/smbd/notify.c index 429723c19e7..3c21ce1e1b5 100644 --- a/source/smbd/notify.c +++ b/source/smbd/notify.c @@ -71,7 +71,8 @@ static void change_notify_reply_packet(char *inbuf, uint32 error_code) */ set_message(outbuf,18,0,False); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("change_notify_reply_packet: send_smb failed.\n"); } /**************************************************************************** diff --git a/source/smbd/notify_kernel.c b/source/smbd/notify_kernel.c index 6509354e9b9..d7408c06b57 100644 --- a/source/smbd/notify_kernel.c +++ b/source/smbd/notify_kernel.c @@ -24,9 +24,9 @@ #if HAVE_KERNEL_CHANGE_NOTIFY extern int DEBUGLEVEL; -static VOLATILE SIG_ATOMIC_T fd_pending; -static VOLATILE SIG_ATOMIC_T signals_received; -static VOLATILE SIG_ATOMIC_T signals_processed; +static VOLATILE sig_atomic_t fd_pending; +static VOLATILE sig_atomic_t signals_received; +static VOLATILE sig_atomic_t signals_processed; #ifndef DN_ACCESS #define DN_ACCESS 0x00000001 /* File accessed in directory */ @@ -62,10 +62,10 @@ struct change_data { /**************************************************************************** the signal handler for change notify *****************************************************************************/ -static void signal_handler(int signal, siginfo_t *info, void *unused) +static void signal_handler(int sig, siginfo_t *info, void *unused) { - BlockSignals(True, signal); - fd_pending = (SIG_ATOMIC_T)info->si_fd; + BlockSignals(True, sig); + fd_pending = (sig_atomic_t)info->si_fd; signals_received++; sys_select_signal(); } @@ -89,7 +89,7 @@ static BOOL kernel_check_notify(connection_struct *conn, uint16 vuid, char *path DEBUG(3,("kernel change notify on %s fd=%d\n", path, (int)fd_pending)); close((int)fd_pending); - fd_pending = (SIG_ATOMIC_T)-1; + fd_pending = (sig_atomic_t)-1; data->directory_handle = -1; signals_processed++; BlockSignals(False, RT_SIGNAL_NOTIFY); @@ -105,7 +105,7 @@ static void kernel_remove_notify(void *datap) int fd = data->directory_handle; if (fd != -1) { if (fd == (int)fd_pending) { - fd_pending = (SIG_ATOMIC_T)-1; + fd_pending = (sig_atomic_t)-1; signals_processed++; BlockSignals(False, RT_SIGNAL_NOTIFY); } diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index dcfc74d19a3..7dfe4b7e1e8 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -96,7 +96,8 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err */ if(params_to_send == 0 && data_to_send == 0) { - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_nt_replies: send_smb failed.\n"); return 0; } @@ -225,7 +226,8 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err params_to_send, data_to_send, paramsize, datasize)); /* Send the packet */ - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_nt_replies: send_smb failed.\n"); pp += params_sent_thistime; pd += data_sent_thistime; @@ -704,6 +706,7 @@ int reply_ntcreate_and_X(connection_struct *conn, files_struct *fsp=NULL; char *p = NULL; BOOL stat_open_only = False; + time_t c_time; START_PROFILE(SMBntcreateX); /* If it's an IPC, use the pipe handler. */ @@ -994,7 +997,16 @@ int reply_ntcreate_and_X(connection_struct *conn, p += 4; /* Create time. */ - put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); + c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + + if (lp_dos_filetime_resolution(SNUM(conn))) { + c_time &= ~1; + sbuf.st_atime &= ~1; + sbuf.st_mtime &= ~1; + sbuf.st_mtime &= ~1; + } + + put_long_date(p,c_time); p += 8; put_long_date(p,sbuf.st_atime); /* access time */ p += 8; @@ -1201,6 +1213,7 @@ static int call_nt_transact_create(connection_struct *conn, int smb_attr; int error_class; uint32 error_code; + time_t c_time; DEBUG(5,("call_nt_transact_create\n")); @@ -1482,7 +1495,16 @@ static int call_nt_transact_create(connection_struct *conn, p += 8; /* Create time. */ - put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); + c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + + if (lp_dos_filetime_resolution(SNUM(conn))) { + c_time &= ~1; + sbuf.st_atime &= ~1; + sbuf.st_mtime &= ~1; + sbuf.st_mtime &= ~1; + } + + put_long_date(p,c_time); p += 8; put_long_date(p,sbuf.st_atime); /* access time */ p += 8; @@ -1882,7 +1904,8 @@ due to being in oplock break state.\n" )); /* We need to send an interim response then receive the rest of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("reply_nttrans: send_smb failed.\n"); while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) { BOOL ret; diff --git a/source/smbd/open.c b/source/smbd/open.c index c6d4a44688c..92b164ce951 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -238,7 +238,7 @@ static int truncate_unless_locked(struct connection_struct *conn, files_struct * { SMB_BIG_UINT mask = (SMB_BIG_UINT)-1; - if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK)){ + if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK,True)){ errno = EACCES; unix_ERR_class = ERRDOS; unix_ERR_code = ERRlock; @@ -492,8 +492,8 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T BOOL opb_ret; - DEBUG(5,("open_mode_check: breaking oplock (%x) on file %s, \ -dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode)); + DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \ +dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode)); /* Oplock break - unlock to request it. */ unlock_share_entry(conn, dev, inode); @@ -596,11 +596,11 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S uint16 port = 0; if (conn->printer) { - /* printers are handled completely differently. Most of the passed parameters are - ignored */ + /* printers are handled completely differently. Most + of the passed parameters are ignored */ *Access = DOS_OPEN_WRONLY; *action = FILE_WAS_CREATED; - return print_fsp_open(conn, fname); + return print_fsp_open(conn); } fsp = file_new(conn); @@ -779,6 +779,14 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", } /* + * If there are any share modes set then the file *did* + * exist. Ensure we return the correct value for action. + */ + + if (num_share_modes > 0) + file_existed = True; + + /* * We exit this block with the share entry *locked*..... */ } diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c index e0b494017a0..cc2581375ea 100644 --- a/source/smbd/oplock.c +++ b/source/smbd/oplock.c @@ -572,7 +572,8 @@ BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token) /* Prepare the SMBlockingX message. */ prepare_break_message( outbuf, fsp, False); - send_smb(smbd_server_fd(), outbuf); + if (!send_smb(smbd_server_fd(), outbuf)) + exit_server("oplock_break_level2: send_smb failed.\n"); } /* @@ -676,13 +677,13 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B messages crossing on the wire. */ - if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL) + if((inbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) { DEBUG(0,("oplock_break: malloc fail for input buffer.\n")); return False; } - if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL) + if((outbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) { DEBUG(0,("oplock_break: malloc fail for output buffer.\n")); free(inbuf); @@ -716,7 +717,8 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT; - send_smb(smbd_server_fd(), outbuf); + if (!send_smb(smbd_server_fd(), outbuf)) + exit_server("oplock_break: send_smb failed.\n"); /* We need this in case a readraw crosses on the wire. */ global_oplock_break = True; @@ -1193,7 +1195,7 @@ setup oplocks for this process BOOL init_oplocks(void) { struct sockaddr_in sock_name; - int len = sizeof(sock_name); + socklen_t len = sizeof(sock_name); DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n")); diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c index e070761f108..39ee3eb86b3 100644 --- a/source/smbd/oplock_linux.c +++ b/source/smbd/oplock_linux.c @@ -25,9 +25,9 @@ extern int DEBUGLEVEL; -static VOLATILE SIG_ATOMIC_T signals_received; -static VOLATILE SIG_ATOMIC_T signals_processed; -static VOLATILE SIG_ATOMIC_T fd_pending; /* the fd of the current pending signal */ +static VOLATILE sig_atomic_t signals_received; +static VOLATILE sig_atomic_t signals_processed; +static VOLATILE sig_atomic_t fd_pending; /* the fd of the current pending signal */ #ifndef F_SETLEASE #define F_SETLEASE 1024 @@ -52,10 +52,10 @@ static VOLATILE SIG_ATOMIC_T fd_pending; /* the fd of the current pending signal /**************************************************************************** handle a LEASE signal, incrementing the signals_received and blocking the signal ****************************************************************************/ -static void signal_handler(int signal, siginfo_t *info, void *unused) +static void signal_handler(int sig, siginfo_t *info, void *unused) { - BlockSignals(True, signal); - fd_pending = (SIG_ATOMIC_T)info->si_fd; + BlockSignals(True, sig); + fd_pending = (sig_atomic_t)info->si_fd; signals_received++; sys_select_signal(); } @@ -127,7 +127,7 @@ static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_l SMB_DEV_T dev; SMB_INO_T inode; SMB_STRUCT_STAT sbuf; - BOOL ret; + BOOL ret = True; if (signals_received == signals_processed) return False; @@ -160,11 +160,11 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode )); out: /* now we can receive more signals */ - fd_pending = (SIG_ATOMIC_T)-1; + fd_pending = (sig_atomic_t)-1; signals_processed++; BlockSignals(False, RT_SIGNAL_LEASE); - return True; + return ret; } diff --git a/source/smbd/password.c b/source/smbd/password.c index 1844b90dd05..5ae1c89ace7 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -110,8 +110,9 @@ user_struct *get_valid_user_struct(uint16 vuid) for (usp=validated_users;usp;usp=usp->next,count++) { if (vuid == usp->vuid) { - if (count > 10) - DLIST_PROMOTE(validated_users, usp); + if (count > 10) { + DLIST_PROMOTE(validated_users, usp); + } return usp; } } @@ -129,6 +130,8 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; + session_yield(vuid); + DLIST_REMOVE(validated_users, vuser); safe_free(vuser->groups); @@ -138,6 +141,20 @@ void invalidate_vuid(uint16 vuid) } /**************************************************************************** +invalidate all vuid entries for this process +****************************************************************************/ +void invalidate_all_vuids(void) +{ + user_struct *usp, *next=NULL; + + for (usp=validated_users;usp;usp=next) { + next = usp->next; + + invalidate_vuid(usp->vuid); + } +} + +/**************************************************************************** return a validated username ****************************************************************************/ char *validated_username(uint16 vuid) @@ -244,8 +261,8 @@ has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest) +int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, + char *domain,BOOL guest) { user_struct *vuser = NULL; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -305,12 +322,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); - fstrcpy(vuser->user.full_name, "<Full Name>"); - if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); - fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); + fstrcpy(vuser->user.full_name, pwfile->pw_gecos); + } + + if (!session_claim(vuser->vuid)) { + DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid)); + invalidate_vuid(vuser->vuid); + return -1; } return vuser->vuid; @@ -430,7 +450,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], if (!lm_pass || !smb_pass) return(False); - DEBUG(4,("Checking SMB password for user %s\n", + DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n", smb_pass->smb_name)); if(smb_pass->acct_ctrl & ACB_DISABLED) { @@ -471,24 +491,24 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], /* Try against the lanman password. smb_pass->smb_passwd == NULL means no password, allow access. */ - DEBUG(4,("Checking LM MD4 password\n")); - if((smb_pass->smb_passwd == NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ)) { - DEBUG(4,("no password required for user %s\n", + DEBUG(4,("smb_password_ok: no password required for user %s\n", smb_pass->smb_name)); return True; } - if((smb_pass->smb_passwd != NULL) && - smb_password_check((char *)lm_pass, + if(lp_lanman_auth() && (smb_pass->smb_passwd != NULL)) { + DEBUG(4,("smb_password_ok: Checking LM password\n")); + + if (smb_password_check((char *)lm_pass, (uchar *)smb_pass->smb_passwd, challenge)) { - DEBUG(4,("LM MD4 password check succeeded\n")); - return(True); + DEBUG(4,("smb_password_ok: LM password check succeeded\n")); + return(True); + } + DEBUG(4,("LM password check failed\n")); } - DEBUG(4,("LM MD4 password check failed\n")); - return False; } @@ -575,37 +595,40 @@ return True if the password is correct, False otherwise BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) { - BOOL ret; + BOOL ret; if ((pwlen == 0) && !lp_null_passwords()) { DEBUG(4,("Null passwords not allowed.\n")); return False; } - if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) - { + if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { /* if 24 bytes long assume it is an encrypted password */ uchar challenge[8]; - if (!last_challenge(challenge)) - { + if (!last_challenge(challenge)) { DEBUG(0,("Error: challenge not done for user=%s\n", user)); return False; } ret = pass_check_smb(user, global_myworkgroup, challenge, (uchar *)password, (uchar *)password, pwd); -#ifdef WITH_PAM - if (ret) { - return pam_accountcheck(user); - } -#endif + + /* + * Try with PAM (may not be compiled in - returns True if not. JRA). + * FIXME ! Should this be called if we're using winbindd ? What about + * non-local accounts ? JRA. + */ + + if (ret) + return (smb_pam_accountcheck(user) == NT_STATUS_NOPROBLEMO); + return ret; } - return pass_check(user, password, pwlen, pwd, + return (pass_check(user, password, pwlen, pwd, lp_update_encrypted() ? - update_smbpassword_file : NULL); + update_smbpassword_file : NULL)); } /**************************************************************************** @@ -725,167 +748,182 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) return(NULL); } - - /**************************************************************************** -check for authority to login to a service with a given username/password + Check for authority to login to a service with a given username/password. + Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ + BOOL authorise_login(int snum,char *user,char *password, int pwlen, BOOL *guest,BOOL *force,uint16 vuid) { - BOOL ok = False; - - *guest = False; - + BOOL ok = False; + user_struct *vuser = get_valid_user_struct(vuid); + #if DEBUG_PASSWORD - DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password)); + DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n", + user,password)); #endif - /* there are several possibilities: - 1) login as the given user with given password - 2) login as a previously registered username with the given password - 3) login as a session list username with the given password - 4) login as a previously validated user/password pair - 5) login as the "user =" user with given password - 6) login as the "user =" user with no password (guest connection) - 7) login as guest user with no password - - if the service is guest_only then steps 1 to 5 are skipped - */ - - if (GUEST_ONLY(snum)) *force = True; + *guest = False; + + if (GUEST_ONLY(snum)) + *force = True; - if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) - { + if (!GUEST_ONLY(snum) && (lp_security() > SEC_SHARE)) { - user_struct *vuser = get_valid_user_struct(vuid); + /* + * We should just use the given vuid from a sessionsetup_and_X. + */ - /* check the given username and password */ - if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen, NULL); - if (ok) DEBUG(3,("ACCEPTED: given username password ok\n")); - } + if (!vuser) { + DEBUG(1,("authorise_login: refusing user %s with no session setup\n", + user)); + return False; + } - /* check for a previously registered guest username */ - if (!ok && (vuser != 0) && vuser->guest) { - if (user_ok(vuser->user.unix_name,snum) && - password_ok(vuser->user.unix_name, password, pwlen, NULL)) { - fstrcpy(user, vuser->user.unix_name); - vuser->guest = False; - DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); - ok = True; + if (!vuser->guest && user_ok(vuser->user.unix_name,snum)) { + fstrcpy(user,vuser->user.unix_name); + *guest = False; + DEBUG(3,("authorise_login: ACCEPTED: validated uid ok as non-guest \ +(user=%s)\n", user)); + return True; + } } - } - + + /* there are several possibilities: + 1) login as the given user with given password + 2) login as a previously registered username with the given password + 3) login as a session list username with the given password + 4) login as a previously validated user/password pair + 5) login as the "user =" user with given password + 6) login as the "user =" user with no password (guest connection) + 7) login as guest user with no password + + if the service is guest_only then steps 1 to 5 are skipped + */ + + if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) { + /* check the given username and password */ + if (!ok && (*user) && user_ok(user,snum)) { + ok = password_ok(user,password, pwlen, NULL); + if (ok) + DEBUG(3,("authorise_login: ACCEPTED: given username (%s) password ok\n", + user )); + } - /* now check the list of session users */ - if (!ok) - { - char *auser; - char *user_list = strdup(session_users); - if (!user_list) return(False); + /* check for a previously registered guest username */ + if (!ok && (vuser != 0) && vuser->guest) { + if (user_ok(vuser->user.unix_name,snum) && + password_ok(vuser->user.unix_name, password, pwlen, NULL)) { + fstrcpy(user, vuser->user.unix_name); + vuser->guest = False; + DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user)); + ok = True; + } + } - for (auser=strtok(user_list,LIST_SEP); - !ok && auser; - auser = strtok(NULL,LIST_SEP)) - { - fstring user2; - fstrcpy(user2,auser); - if (!user_ok(user2,snum)) continue; + /* now check the list of session users */ + if (!ok) { + char *auser; + char *user_list = strdup(session_users); + if (!user_list) + return(False); + + for (auser=strtok(user_list,LIST_SEP); !ok && auser; + auser = strtok(NULL,LIST_SEP)) { + fstring user2; + fstrcpy(user2,auser); + if (!user_ok(user2,snum)) + continue; - if (password_ok(user2,password, pwlen, NULL)) { - ok = True; - fstrcpy(user,user2); - DEBUG(3,("ACCEPTED: session list username and given password ok\n")); - } - } - free(user_list); - } + if (password_ok(user2,password, pwlen, NULL)) { + ok = True; + fstrcpy(user,user2); + DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \ +and given password ok\n", user)); + } + } - /* check for a previously validated username/password pair */ - if (!ok && (lp_security() > SEC_SHARE) && - (vuser != 0) && !vuser->guest && - user_ok(vuser->user.unix_name,snum)) { - fstrcpy(user,vuser->user.unix_name); - *guest = False; - DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); - ok = True; - } + free(user_list); + } - /* check for a rhosts entry */ - if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) { - ok = True; - DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n")); - } + /* check for a previously validated username/password pair */ + if (!ok && (lp_security() > SEC_SHARE) && (vuser != 0) && !vuser->guest && + user_ok(vuser->user.unix_name,snum)) { + fstrcpy(user,vuser->user.unix_name); + *guest = False; + DEBUG(3,("authorise_login: ACCEPTED: validated uid (%s) as non-guest\n", + user)); + ok = True; + } - /* check the user= fields and the given password */ - if (!ok && lp_username(snum)) { - char *auser; - pstring user_list; - StrnCpy(user_list,lp_username(snum),sizeof(pstring)); + /* check for a rhosts entry */ + if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) { + ok = True; + DEBUG(3,("authorise_login: ACCEPTED: hosts equiv or rhosts entry for %s\n", + user)); + } - pstring_sub(user_list,"%S",lp_servicename(snum)); - - for (auser=strtok(user_list,LIST_SEP); - auser && !ok; - auser = strtok(NULL,LIST_SEP)) - { - if (*auser == '@') - { - auser = validate_group(auser+1,password,pwlen,snum); - if (auser) - { - ok = True; - fstrcpy(user,auser); - DEBUG(3,("ACCEPTED: group username and given password ok\n")); - } - } - else - { - fstring user2; - fstrcpy(user2,auser); - if (user_ok(user2,snum) && - password_ok(user2,password,pwlen,NULL)) - { - ok = True; - fstrcpy(user,user2); - DEBUG(3,("ACCEPTED: user list username and given password ok\n")); - } - } - } - } - } /* not guest only */ + /* check the user= fields and the given password */ + if (!ok && lp_username(snum)) { + char *auser; + pstring user_list; + StrnCpy(user_list,lp_username(snum),sizeof(pstring)); - /* check for a normal guest connection */ - if (!ok && GUEST_OK(snum)) - { - fstring guestname; - StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); - if (Get_Pwnam(guestname,True)) - { - fstrcpy(user,guestname); - ok = True; - DEBUG(3,("ACCEPTED: guest account and guest ok\n")); + pstring_sub(user_list,"%S",lp_servicename(snum)); + + for (auser=strtok(user_list,LIST_SEP); auser && !ok; + auser = strtok(NULL,LIST_SEP)) { + if (*auser == '@') { + auser = validate_group(auser+1,password,pwlen,snum); + if (auser) { + ok = True; + fstrcpy(user,auser); + DEBUG(3,("authorise_login: ACCEPTED: group username \ +and given password ok (%s)\n", user)); + } + } else { + fstring user2; + fstrcpy(user2,auser); + if (user_ok(user2,snum) && password_ok(user2,password,pwlen,NULL)) { + ok = True; + fstrcpy(user,user2); + DEBUG(3,("authorise_login: ACCEPTED: user list username \ +and given password ok (%s)\n", user)); + } + } + } + } + } /* not guest only */ + + /* check for a normal guest connection */ + if (!ok && GUEST_OK(snum)) { + fstring guestname; + StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); + if (Get_Pwnam(guestname,True)) { + fstrcpy(user,guestname); + ok = True; + DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n", + user)); + } else { + DEBUG(0,("authorise_login: Invalid guest account %s??\n",guestname)); + } + *guest = True; } - else - DEBUG(0,("Invalid guest account %s??\n",guestname)); - *guest = True; - } - if (ok && !user_ok(user,snum)) - { - DEBUG(0,("rejected invalid user %s\n",user)); - ok = False; - } + if (ok && !user_ok(user,snum)) { + DEBUG(0,("authorise_login: rejected invalid user %s\n",user)); + ok = False; + } - return(ok); + return(ok); } - /**************************************************************************** -read the a hosts.equiv or .rhosts file and check if it -allows this user from this machine + Read the a hosts.equiv or .rhosts file and check if it + allows this user from this machine. ****************************************************************************/ + static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) { int plus_allowed = 1; @@ -1112,96 +1150,103 @@ BOOL server_validate(char *user, char *domain, char *pass, int passlen, char *ntpass, int ntpasslen) { - struct cli_state *cli; - static unsigned char badpass[24]; - static BOOL tested_password_server = False; - static BOOL bad_password_server = False; + struct cli_state *cli; + static unsigned char badpass[24]; + static fstring baduser; + static BOOL tested_password_server = False; + static BOOL bad_password_server = False; - cli = server_client(); + cli = server_client(); - if (!cli->initialised) { - DEBUG(1,("password server %s is not connected\n", cli->desthost)); - return(False); - } + if (!cli->initialised) { + DEBUG(1,("password server %s is not connected\n", cli->desthost)); + return(False); + } - if(badpass[0] == 0) - memset(badpass, 0x1f, sizeof(badpass)); + if(badpass[0] == 0) + memset(badpass, 0x1f, sizeof(badpass)); - if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { - /* - * Very unlikely, our random bad password is the same as the users - * password. */ - memset(badpass, badpass[0]+1, sizeof(badpass)); - } + if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { + /* + * Very unlikely, our random bad password is the same as the users + * password. + */ + memset(badpass, badpass[0]+1, sizeof(badpass)); + } - /* - * Attempt a session setup with a totally incorrect password. - * If this succeeds with the guest bit *NOT* set then the password - * server is broken and is not correctly setting the guest bit. We - * need to detect this as some versions of NT4.x are broken. JRA. - */ + if(baduser[0] == 0) { + fstrcpy(baduser, INVALID_USER_PREFIX); + fstrcat(baduser, global_myname); + } + + /* + * Attempt a session setup with a totally incorrect password. + * If this succeeds with the guest bit *NOT* set then the password + * server is broken and is not correctly setting the guest bit. We + * need to detect this as some versions of NT4.x are broken. JRA. + */ - if(!tested_password_server) { - if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), - (char *)badpass, sizeof(badpass), domain)) { + if(!tested_password_server) { + if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass), + (char *)badpass, sizeof(badpass), domain)) { - /* - * We connected to the password server so we - * can say we've tested it. - */ - tested_password_server = True; + /* + * We connected to the password server so we + * can say we've tested it. + */ + tested_password_server = True; - if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { - DEBUG(0,("server_validate: password server %s allows users as non-guest \ + if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { + DEBUG(0,("server_validate: password server %s allows users as non-guest \ with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ + DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ use this machine as the password server.\n")); - cli_ulogoff(cli); + cli_ulogoff(cli); - /* - * Password server has the bug. - */ - bad_password_server = True; - return False; - } - cli_ulogoff(cli); - } - } else { + /* + * Password server has the bug. + */ + bad_password_server = True; + return False; + } + cli_ulogoff(cli); + } + } else { - /* - * We have already tested the password server. - * Fail immediately if it has the bug. - */ + /* + * We have already tested the password server. + * Fail immediately if it has the bug. + */ - if(bad_password_server) { - DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \ + if(bad_password_server) { + DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \ with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \ + DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \ use this machine as the password server.\n")); - return False; - } - } + return False; + } + } - /* - * Now we know the password server will correctly set the guest bit, or is - * not guest enabled, we can try with the real password. - */ + /* + * Now we know the password server will correctly set the guest bit, or is + * not guest enabled, we can try with the real password. + */ - if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli->desthost)); - return False; - } + if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", cli->desthost)); + return False; + } - /* if logged in as guest then reject */ - if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); - cli_ulogoff(cli); - return(False); - } + /* if logged in as guest then reject */ + if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); + cli_ulogoff(cli); + return(False); + } - cli_ulogoff(cli); + cli_ulogoff(cli); - return(True); + return(True); } /*********************************************************************** @@ -1210,13 +1255,12 @@ use this machine as the password server.\n")); ************************************************************************/ static BOOL connect_to_domain_password_server(struct cli_state *pcli, - char *server, - unsigned char *trust_passwd) + char *server, unsigned char *trust_passwd) { struct in_addr dest_ip; fstring remote_machine; - if(cli_initialise(pcli) == False) { + if(!cli_initialise(pcli)) { DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); return False; } @@ -1514,9 +1558,9 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password for our primary domain */ - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time)) + if (!secrets_fetch_trust_account_password(global_myworkgroup, trust_passwd, &last_change_time)) { - DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", lp_workgroup())); + DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", global_myworkgroup)); return False; } diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index a9c88212387..4832184df71 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -459,19 +459,60 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, } /**************************************************************************** + Ensure the enforced permissions for this share apply. +****************************************************************************/ + +static mode_t apply_default_perms(files_struct *fsp, mode_t perms, mode_t type) +{ + int snum = SNUM(fsp->conn); + mode_t and_bits = (mode_t)0; + mode_t or_bits = (mode_t)0; + + /* Get the initial bits to apply. */ + + if (fsp->is_directory) { + and_bits = lp_dir_security_mask(snum); + or_bits = lp_force_dir_security_mode(snum); + } else { + and_bits = lp_security_mask(snum); + or_bits = lp_force_security_mode(snum); + } + + /* Now bounce them into the S_USR space. */ + switch(type) { + case S_IRUSR: + and_bits = unix_perms_to_acl_perms(and_bits, S_IRUSR, S_IWUSR, S_IXUSR); + or_bits = unix_perms_to_acl_perms(or_bits, S_IRUSR, S_IWUSR, S_IXUSR); + break; + case S_IRGRP: + and_bits = unix_perms_to_acl_perms(and_bits, S_IRGRP, S_IWGRP, S_IXGRP); + or_bits = unix_perms_to_acl_perms(or_bits, S_IRGRP, S_IWGRP, S_IXGRP); + break; + case S_IROTH: + and_bits = unix_perms_to_acl_perms(and_bits, S_IROTH, S_IWOTH, S_IXOTH); + or_bits = unix_perms_to_acl_perms(or_bits, S_IROTH, S_IWOTH, S_IXOTH); + break; + } + + return ((perms & and_bits)|or_bits); +} + +/**************************************************************************** A well formed POSIX file or default ACL has at least 3 entries, a SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ. In addition, the owner must always have at least read access. When using this call on get_acl, the pst struct is valid and contains the mode of the file. When using this call on set_acl, the pst struct has - been modified to have a mode of r--------. + been modified to have a mode containing the default for this file or directory + type. ****************************************************************************/ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, files_struct *fsp, DOM_SID *pfile_owner_sid, DOM_SID *pfile_grp_sid, - SMB_STRUCT_STAT *pst) + SMB_STRUCT_STAT *pst, + BOOL setting_acl) { extern DOM_SID global_sid_World; canon_ace *pace; @@ -481,14 +522,40 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, for (pace = *pp_ace; pace; pace = pace->next) { if (pace->type == SMB_ACL_USER_OBJ) { - /* Ensure owner has read access. */ - if (pace->perms == (mode_t)0) - pace->perms = S_IRUSR; + + if (setting_acl) { + /* Ensure owner has read access. */ + pace->perms |= S_IRUSR; + if (fsp->is_directory) + pace->perms |= (S_IWUSR|S_IXUSR); + + /* + * Ensure create mask/force create mode is respected on set. + */ + + pace->perms = apply_default_perms(fsp, pace->perms, S_IRUSR); + } + got_user = True; - } else if (pace->type == SMB_ACL_GROUP_OBJ) + } else if (pace->type == SMB_ACL_GROUP_OBJ) { + + /* + * Ensure create mask/force create mode is respected on set. + */ + + if (setting_acl) + pace->perms = apply_default_perms(fsp, pace->perms, S_IRGRP); got_grp = True; - else if (pace->type == SMB_ACL_OTHER) + } else if (pace->type == SMB_ACL_OTHER) { + + /* + * Ensure create mask/force create mode is respected on set. + */ + + if (setting_acl) + pace->perms = apply_default_perms(fsp, pace->perms, S_IROTH); got_other = True; + } } if (!got_user) { @@ -502,10 +569,7 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, pace->owner_type = UID_ACE; pace->unix_ug.uid = pst->st_uid; pace->sid = *pfile_owner_sid; - /* Ensure owner has read access. */ pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); - if (pace->perms == (mode_t)0) - pace->perms = S_IRUSR; pace->attr = ALLOW_ACE; DLIST_ADD(*pp_ace, pace); @@ -567,18 +631,19 @@ static BOOL create_canon_ace_lists(files_struct *fsp, canon_ace *current_ace = NULL; BOOL got_dir_allow = False; BOOL got_file_allow = False; - int i; + int i, j; *ppfile_ace = NULL; *ppdir_ace = NULL; + /* + * Convert the incoming ACL into a more regular form. + */ + for(i = 0; i < dacl->num_aces; i++) { - enum SID_NAME_USE sid_type; SEC_ACE *psa = &dacl->ace[i]; if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) && (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) { - free_canon_ace_list(file_ace); - free_canon_ace_list(dir_ace); DEBUG(3,("create_canon_ace_lists: unable to set anything but an ALLOW or DENY ACE.\n")); return False; } @@ -600,6 +665,50 @@ static BOOL create_canon_ace_lists(files_struct *fsp, if(psa->info.mask != UNIX_ACCESS_NONE) psa->info.mask &= ~UNIX_ACCESS_NONE; + } + + /* + * Deal with the fact that NT 4.x re-writes the canonical format + * that we return for default ACLs. If a directory ACE is identical + * to a inherited directory ACE then NT changes the bits so that the + * first ACE is set to OI|IO and the second ACE for this SID is set + * to CI. We need to repair this. JRA. + */ + + for(i = 0; i < dacl->num_aces; i++) { + SEC_ACE *psa1 = &dacl->ace[i]; + + for (j = i + 1; j < dacl->num_aces; j++) { + SEC_ACE *psa2 = &dacl->ace[j]; + + if (psa1->info.mask != psa2->info.mask) + continue; + + if (!sid_equal(&psa1->sid, &psa2->sid)) + continue; + + /* + * Ok - permission bits and SIDs are equal. + * Check if flags were re-written. + */ + + if (psa1->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + + psa1->flags |= (psa2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)); + psa2->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT); + + } else if (psa2->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + + psa2->flags |= (psa1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)); + psa1->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT); + + } + } + } + + for(i = 0; i < dacl->num_aces; i++) { + enum SID_NAME_USE sid_type; + SEC_ACE *psa = &dacl->ace[i]; /* * Create a cannon_ace entry representing this NT DACL ACE. @@ -652,14 +761,17 @@ static BOOL create_canon_ace_lists(files_struct *fsp, */ if(sid_equal(¤t_ace->sid, pfile_owner_sid)) { - /* Note we should apply the default mode/mask here.... FIXME ! JRA */ + current_ace->type = SMB_ACL_USER_OBJ; + } else if( sid_equal(¤t_ace->sid, pfile_grp_sid)) { - /* Note we should apply the default mode/mask here.... FIXME ! JRA */ + current_ace->type = SMB_ACL_GROUP_OBJ; + } else if( sid_equal(¤t_ace->sid, &global_sid_World)) { - /* Note we should apply the default mode/mask here.... FIXME ! JRA */ + current_ace->type = SMB_ACL_OTHER; + } else { /* * Could be a SMB_ACL_USER or SMB_ACL_GROUP. Check by @@ -1090,6 +1202,37 @@ static void process_deny_list( canon_ace **pp_ace_list ) } /**************************************************************************** + Create a default mode that will be used if a security descriptor entry has + no user/group/world entries. +****************************************************************************/ + +static mode_t create_default_mode(files_struct *fsp, BOOL interitable_mode) +{ + int snum = SNUM(fsp->conn); + mode_t and_bits = (mode_t)0; + mode_t or_bits = (mode_t)0; + mode_t mode = interitable_mode ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name) : S_IRUSR; + + if (fsp->is_directory) + mode |= (S_IWUSR|S_IXUSR); + + /* + * Now AND with the create mode/directory mode bits then OR with the + * force create mode/force directory mode bits. + */ + + if (fsp->is_directory) { + and_bits = lp_dir_security_mask(snum); + or_bits = lp_force_dir_security_mode(snum); + } else { + and_bits = lp_security_mask(snum); + or_bits = lp_force_security_mode(snum); + } + + return ((mode & and_bits)|or_bits); +} + +/**************************************************************************** Unpack a SEC_DESC into two canonical ace lists. We don't depend on this succeeding. ****************************************************************************/ @@ -1166,14 +1309,12 @@ static BOOL unpack_canon_ace(files_struct *fsp, /* * A default 3 element mode entry for a file should be r-- --- ---. - * A default 3 element mode entry for a directory should be r-x --- ---. + * A default 3 element mode entry for a directory should be rwx --- ---. */ - pst->st_mode = S_IRUSR; - if (fsp->is_directory) - pst->st_mode |= S_IXUSR; + pst->st_mode = create_default_mode(fsp, False); - if (!ensure_canon_entry_valid(&file_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst)) { + if (!ensure_canon_entry_valid(&file_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) { free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -1183,15 +1324,13 @@ static BOOL unpack_canon_ace(files_struct *fsp, /* * A default inheritable 3 element mode entry for a directory should be the - * mode Samba will use to create a file within. Ensure user x bit is set if + * mode Samba will use to create a file within. Ensure user rwx bits are set if * it's a directory. */ - pst->st_mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name); - if (fsp->is_directory) - pst->st_mode |= S_IXUSR; + pst->st_mode = create_default_mode(fsp, True); - if (!ensure_canon_entry_valid(&dir_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst)) { + if (!ensure_canon_entry_valid(&dir_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) { free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -1206,7 +1345,6 @@ static BOOL unpack_canon_ace(files_struct *fsp, } - /****************************************************************************** When returning permissions, try and fit NT display semantics if possible. Note the the canon_entries here must have been malloced. @@ -1377,7 +1515,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ * This next call will ensure we have at least a user/group/world set. */ - if (!ensure_canon_entry_valid(&list_head, fsp, powner, pgroup, psbuf)) + if (!ensure_canon_entry_valid(&list_head, fsp, powner, pgroup, psbuf, False)) goto fail; arrange_posix_perms(fsp->fsp_name,&list_head ); @@ -1387,7 +1525,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ * acl_mask. Ensure all DENY Entries are at the start of the list. */ - DEBUG(10,("canonicalize_acl: ace entries before arrange :\n")); + DEBUG(10,("canonicalise_acl: ace entries before arrange :\n")); for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) { next_ace = ace->next; @@ -1405,7 +1543,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ } } - print_canon_ace_list( "canonicalize_acl: ace entries after arrange", list_head ); + print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head ); return list_head; @@ -1503,7 +1641,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau if (map_acl_perms_to_permset(p_ace->perms, &the_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to create permset for mode (%u) on entry %d. (%s)\n", - p_ace->perms, i, strerror(errno) )); + (unsigned int)p_ace->perms, i, strerror(errno) )); goto done; } @@ -1598,11 +1736,14 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau static BOOL convert_canon_ace_to_posix_perms( files_struct *fsp, canon_ace *file_ace_list, mode_t *posix_perms) { + int snum = SNUM(fsp->conn); size_t ace_count = count_canon_ace_list(file_ace_list); canon_ace *ace_p; canon_ace *owner_ace = NULL; canon_ace *group_ace = NULL; canon_ace *other_ace = NULL; + mode_t and_bits; + mode_t or_bits; if (ace_count != 3) { DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE entries for file %s to convert to \ @@ -1637,8 +1778,23 @@ posix perms.\n", fsp->fsp_name )); /* The owner must have at least read access. */ - if (*posix_perms == (mode_t)0) - *posix_perms = S_IRUSR; + *posix_perms |= S_IRUSR; + if (fsp->is_directory) + *posix_perms |= (S_IWUSR|S_IXUSR); + + /* If requested apply the masks. */ + + /* Get the initial bits to apply. */ + + if (fsp->is_directory) { + and_bits = lp_dir_security_mask(snum); + or_bits = lp_force_dir_security_mode(snum); + } else { + and_bits = lp_security_mask(snum); + or_bits = lp_force_security_mode(snum); + } + + *posix_perms = (((*posix_perms) & and_bits)|or_bits); DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o to perm=0%o for file %s.\n", (int)owner_ace->perms, (int)group_ace->perms, (int)other_ace->perms, (int)*posix_perms, @@ -1831,6 +1987,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) canon_ace *file_ace_list = NULL; canon_ace *dir_ace_list = NULL; BOOL acl_perms = False; + mode_t orig_mode = (mode_t)0; + uid_t orig_uid; + gid_t orig_gid; DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); @@ -1846,6 +2005,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) return False; } + /* Save the original elements we check against. */ + orig_mode = sbuf.st_mode; + orig_uid = sbuf.st_uid; + orig_gid = sbuf.st_gid; + /* * Unpack the user/group/world id's. */ @@ -1857,7 +2021,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * Do we need to chown ? */ - if((user != (uid_t)-1 || grp != (uid_t)-1) && (sbuf.st_uid != user || sbuf.st_gid != grp)) { + if((user != (uid_t)-1 || grp != (uid_t)-1) && (orig_uid != user || orig_gid != grp)) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); @@ -1889,6 +2053,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) if(ret != 0) return False; } + + /* Save the original elements we check against. */ + orig_mode = sbuf.st_mode; + orig_uid = sbuf.st_uid; + orig_gid = sbuf.st_gid; } create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); @@ -1932,12 +2101,25 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) } } - if (acl_perms && acl_set_support && fsp->is_directory && dir_ace_list) { - if (!set_canon_ace_list(fsp, dir_ace_list, True, &acl_set_support)) { - DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) )); - free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); - return False; + if (acl_perms && acl_set_support && fsp->is_directory) { + if (dir_ace_list) { + if (!set_canon_ace_list(fsp, dir_ace_list, True, &acl_set_support)) { + DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) )); + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + return False; + } + } else { + + /* + * No default ACL - delete one if it exists. + */ + + if (sys_acl_delete_def_file(dos_to_unix(fsp->fsp_name,False)) == -1) { + DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); + free_canon_ace_list(file_ace_list); + return False; + } } } @@ -1956,7 +2138,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) return False; } - if (sbuf.st_mode != posix_perms) { + if (orig_mode != posix_perms) { DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", fsp->fsp_name, (unsigned int)posix_perms )); diff --git a/source/smbd/process.c b/source/smbd/process.c index 71d3c57b23c..168cfd440e5 100644 --- a/source/smbd/process.c +++ b/source/smbd/process.c @@ -48,7 +48,7 @@ extern char *last_inbuf; extern char *InBuffer; extern char *OutBuffer; extern int smb_read_error; -extern VOLATILE SIG_ATOMIC_T reload_after_sighup; +extern VOLATILE sig_atomic_t reload_after_sighup; extern BOOL global_machine_password_needs_changing; extern fstring global_myworkgroup; extern pstring global_myname; @@ -612,7 +612,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize { static pid_t pid= (pid_t)-1; int outsize = 0; - extern int global_smbpid; + extern uint16 global_smbpid; type &= 0xff; @@ -693,6 +693,12 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize if (!(flags & AS_USER)) unbecome_user(); + /* does this protocol need a valid tree connection? */ + if ((flags & AS_USER) && !conn) { + return ERROR(ERRSRV, ERRinvnid); + } + + /* does this protocol need to be run as the connected user? */ if ((flags & AS_USER) && !become_user(conn,session_tag)) { if (flags & AS_GUEST) @@ -781,12 +787,12 @@ static BOOL smbd_process_limit(void) /* Always add one to the smbd process count, as exit_server() always * subtracts one. */ - tdb_lock_bystring(conn_tdb_ctx(), "INFO/total_smbds"); - total_smbds = tdb_fetch_int(conn_tdb_ctx(), "INFO/total_smbds"); - total_smbds = total_smbds < 0 ? 1 : total_smbds + 1; - tdb_store_int(conn_tdb_ctx(), "INFO/total_smbds", total_smbds); - tdb_unlock_bystring(conn_tdb_ctx(), "INFO/total_smbds"); - + + total_smbds = 1; /* In case we need to create the entry. */ + + if (tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1) + return True; + return total_smbds > lp_max_smbd_processes(); } else @@ -822,7 +828,7 @@ void process_smb(char *inbuf, char *outbuf) static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) ); - send_smb(smbd_server_fd(),(char *)buf); + (void)send_smb(smbd_server_fd(),(char *)buf); exit_server("connection denied"); } } @@ -860,7 +866,8 @@ void process_smb(char *inbuf, char *outbuf) nread, smb_len(outbuf))); } else - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("process_smb: send_smb failed.\n"); } trans_num++; } @@ -1183,8 +1190,8 @@ void smbd_process(void) time_t last_timeout_processing_time = time(NULL); unsigned int num_smbs = 0; - InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); - OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); + InBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN); + OutBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN); if ((InBuffer == NULL) || (OutBuffer == NULL)) return; @@ -1196,6 +1203,9 @@ void smbd_process(void) /* re-initialise the timezone */ TimeInit(); + /* register our message handlers */ + message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis); + while (True) { int deadtime = lp_deadtime()*60; int select_timeout = setup_select_timeout(); @@ -1210,7 +1220,7 @@ void smbd_process(void) lp_talloc_free(); main_loop_talloc_free(); - while (!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout)) { + while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) { if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time)) return; num_smbs = 0; /* Reset smb counter. */ @@ -1246,7 +1256,7 @@ void smbd_process(void) if ((num_smbs % 200) == 0) { time_t new_check_time = time(NULL); - if(last_timeout_processing_time - new_check_time >= (select_timeout/1000)) { + if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) { if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time)) return; num_smbs = 0; /* Reset smb counter. */ diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index ccb5534641a..caf3997ba80 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -277,11 +277,6 @@ static int xdr_getquota_args(XDR *xdrsp, struct getquota_args *args) static int xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr) { - gqr_status status; - union { - rquota gqr_rquota; - } getquota_rslt_u; - if (!xdr_int(xdrsp, "astat)) { DEBUG(6,("nfs_quotas: Status bad or zero\n")); return 0; @@ -322,6 +317,9 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B int len; static struct timeval timeout = {2,0}; enum clnt_stat clnt_stat; + BOOL ret = True; + + *bsize = *dfree = *dsize = (SMB_BIG_UINT)0; len=strcspn(mnttype, ":"); pathname=strstr(mnttype, ":"); @@ -338,15 +336,21 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B DEBUG(5,("nfs_quotas: Asking for host \"%s\" rpcprog \"%i\" rpcvers \"%i\" network \"%s\"\n", host, RQUOTAPROG, RQUOTAVERS, "udp")); - if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) != NULL) { - clnt->cl_auth = authunix_create_default(); - DEBUG(9,("nfs_quotas: auth_success\n")); + if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) == NULL) { + ret = False; + goto out; + } - clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, xdr_getquota_args, (caddr_t)&args, xdr_getquota_rslt, (caddr_t)&gqr, timeout); - if (clnt_stat == RPC_SUCCESS) - DEBUG(9,("nfs_quotas: rpccall_success\n")); - }; + clnt->cl_auth = authunix_create_default(); + DEBUG(9,("nfs_quotas: auth_success\n")); + clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, xdr_getquota_args, (caddr_t)&args, xdr_getquota_rslt, (caddr_t)&gqr, timeout); + + if (clnt_stat != RPC_SUCCESS) { + DEBUG(9,("nfs_quotas: clnt_call fail\n")); + ret = False; + goto out; + } /* * quotastat returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is @@ -354,26 +358,30 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B * something sensible. */ - if (quotastat == 1) { + switch ( quotastat ) { + case 0: + DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat )); + ret = False; + goto out; + + case 1: DEBUG(9,("nfs_quotas: Good quota data\n")); D.dqb_bsoftlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit; D.dqb_bhardlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit; D.dqb_curblocks = gqr.getquota_rslt_u.gqr_rquota.rq_curblocks; - } + break; - if (quotastat == 0 || quotastat == 3) { + case 2: + case 3: D.dqb_bsoftlimit = 1; D.dqb_curblocks = 1; - DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat )); - } + DEBUG(9,("nfs_quotas: Remote Quotas returned \"%i\" \n", quotastat )); + break; - if (quotastat == 2) { - DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat )); - auth_destroy(clnt->cl_auth); - clnt_destroy(clnt); - free(cutstr); - return(False); - } + default: + DEBUG(9,("nfs_quotas: Remote Quotas Questionable! Error \"%i\" \n", quotastat )); + break; + } DEBUG(10,("nfs_quotas: Let`s look at D a bit closer... status \"%i\" bsize \"%i\" active? \"%i\" bhard \"%i\" bsoft \"%i\" curb \"%i\" \n", quotastat, @@ -395,14 +403,19 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B } else *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; - auth_destroy(clnt->cl_auth); - clnt_destroy(clnt); + out: + + if (clnt) { + if (clnt->cl_auth) + auth_destroy(clnt->cl_auth); + clnt_destroy(clnt); + } DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize)); - free(cutstr); + safe_free(cutstr); DEBUG(10,("nfs_quotas: End of nfs_quotas\n" )); - return(True); + return ret; } #endif @@ -438,7 +451,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U return(False) ; devno = sbuf.st_dev ; - DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,devno)); + DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,(unsigned int)devno)); if ( devno != devno_cached ) { devno_cached = devno ; #if defined(SUNOS5) @@ -446,7 +459,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U return(False) ; found = False ; - slprintf(devopt, sizeof(devopt) - 1, "dev=%x", devno); + slprintf(devopt, sizeof(devopt) - 1, "dev=%x", (unsigned int)devno); while (getmntent(fd, &mnt) == 0) { if( !hasmntopt(&mnt, devopt) ) continue; @@ -473,7 +486,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U while ((mnt = getmntent(fd)) != NULL) { if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 ) continue ; - DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n", mnt->mnt_dir,sbuf.st_dev)); + DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt->mnt_dir,(unsigned int)sbuf.st_dev)); if (sbuf.st_dev == devno) { found = True ; break; diff --git a/source/smbd/reply.c b/source/smbd/reply.c index f6d2c97cb58..22b213b3729 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -54,7 +54,6 @@ static void overflow_attack(int len) dbgtext( "attempting to exploit an old bug.\n" ); dbgtext( "Attack was from IP = %s.\n", client_addr() ); } - exit_server("possible attack"); } @@ -170,11 +169,10 @@ static int connection_error(char *inbuf,char *outbuf,int ecode) return(ERROR(ERRSRV,ecode)); } - - /**************************************************************************** parse a share descriptor string ****************************************************************************/ + static void parse_connect(char *p,char *service,char *user, char *password,int *pwlen,char *dev) { @@ -228,13 +226,21 @@ int reply_tcon(connection_struct *conn, parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev); + /* + * If the vuid is valid, we should be using that.... + */ + + if (*user == '\0' && (lp_security() != SEC_SHARE) && validated_username(vuid)) { + pstrcpy(user,validated_username(vuid)); + } + /* * Ensure the user and password names are in UNIX codepage format. */ - dos_to_unix(user,True); + pstrcpy(user,dos_to_unix(user,False)); if (!doencrypt) - dos_to_unix(password,True); + pstrcpy(password,dos_to_unix(password,False)); /* * Pass the user through the NT -> unix user mapping @@ -270,6 +276,7 @@ int reply_tcon(connection_struct *conn, /**************************************************************************** Reply to a tcon and X. ****************************************************************************/ + int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { fstring service; @@ -293,6 +300,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if (passlen > MAX_PASS_LEN) { overflow_attack(passlen); + return(ERROR(ERRDOS,ERRbuftoosmall)); } memcpy(password,smb_buf(inbuf),passlen); @@ -320,12 +328,20 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt DEBUG(4,("Got device type %s\n",devicename)); /* + * If the vuid is valid, we should be using that.... + */ + + if (*user == '\0' && (lp_security() != SEC_SHARE) && validated_username(vuid)) { + pstrcpy(user,validated_username(vuid)); + } + + /* * Ensure the user and password names are in UNIX codepage format. */ - dos_to_unix(user,True); + pstrcpy(user,dos_to_unix(user,False)); if (!doencrypt) - dos_to_unix(password,True); + pstrcpy(password,dos_to_unix(password,False)); /* * Pass the user through the NT -> unix user mapping @@ -394,7 +410,6 @@ int reply_unknown(char *inbuf,char *outbuf) return(ERROR(ERRSRV,ERRunknownsmb)); } - /**************************************************************************** reply to an ioctl ****************************************************************************/ @@ -563,47 +578,48 @@ static BOOL check_server_security(char *orig_user, char *domain, char *unix_user char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen) { - BOOL ret = False; + BOOL ret = False; - if(lp_security() != SEC_SERVER) - return False; + if(lp_security() != SEC_SERVER) + return False; - if (!check_domain_match(orig_user, domain)) - return False; + if (!check_domain_match(orig_user, domain)) + return False; - ret = server_validate(orig_user, domain, - smb_apasswd, smb_apasslen, - smb_ntpasswd, smb_ntpasslen); - if(ret) { - struct passwd *pwd = NULL; + ret = server_validate(orig_user, domain, + smb_apasswd, smb_apasslen, + smb_ntpasswd, smb_ntpasslen); - /* - * User validated ok against Domain controller. - * If the admin wants us to try and create a UNIX - * user on the fly, do so. - * Note that we can never delete users when in server - * level security as we never know if it was a failure - * due to a bad password, or the user really doesn't exist. - */ - if(lp_adduser_script() && !(pwd = smb_getpwnam(unix_user,True))) { - smb_create_user(unix_user, NULL); - } + if(ret) { + struct passwd *pwd = NULL; - if(lp_adduser_script() && pwd) { - SMB_STRUCT_STAT st; + /* + * User validated ok against Domain controller. + * If the admin wants us to try and create a UNIX + * user on the fly, do so. + * Note that we can never delete users when in server + * level security as we never know if it was a failure + * due to a bad password, or the user really doesn't exist. + */ - /* - * Also call smb_create_user if the users home directory - * doesn't exist. Used with winbindd to allow the script to - * create the home directory for a user mapped with winbindd. - */ + if(lp_adduser_script() && !(pwd = smb_getpwnam(unix_user,True))) + smb_create_user(unix_user, NULL); - if (pwd->pw_shell && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT)) - smb_create_user(unix_user, pwd->pw_dir); - } - } + if(lp_adduser_script() && pwd) { + SMB_STRUCT_STAT st; - return ret; + /* + * Also call smb_create_user if the users home directory + * doesn't exist. Used with winbindd to allow the script to + * create the home directory for a user mapped with winbindd. + */ + + if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT)) + smb_create_user(unix_user, pwd->pw_dir); + } + } + + return ret; } /**************************************************************************** @@ -648,7 +664,7 @@ static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user * create the home directory for a user mapped with winbindd. */ - if (pwd->pw_shell && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT)) + if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT)) smb_create_user(unix_user, pwd->pw_dir); } @@ -690,7 +706,7 @@ reply to a session setup command int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - uint16 sess_vuid; + int sess_vuid; gid_t gid; uid_t uid; int smb_bufsize; @@ -705,19 +721,22 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int BOOL guest=False; static BOOL done_sesssetup = False; BOOL doencrypt = SMBENCRYPT(); - char *domain = ""; + fstring domain; START_PROFILE(SMBsesssetupX); *smb_apasswd = 0; *smb_ntpasswd = 0; - + *domain = 0; + smb_bufsize = SVAL(inbuf,smb_vwv2); if (Protocol < PROTOCOL_NT1) { smb_apasslen = SVAL(inbuf,smb_vwv7); - if (smb_apasslen > MAX_PASS_LEN) + if (smb_apasslen > MAX_PASS_LEN) { overflow_attack(smb_apasslen); - + return(ERROR(ERRDOS,ERRbuftoosmall)); + } + memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); smb_apasswd[smb_apasslen] = 0; pstrcpy(user,smb_buf(inbuf)+smb_apasslen); @@ -725,7 +744,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int * Incoming user is in DOS codepage format. Convert * to UNIX. */ - dos_to_unix(user,True); + pstrcpy(user,dos_to_unix(user,False)); if (!doencrypt && (lp_security() != SEC_SERVER)) { smb_apasslen = strlen(smb_apasswd); @@ -755,6 +774,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int if (passlen1 > MAX_PASS_LEN) { overflow_attack(passlen1); + return(ERROR(ERRDOS,ERRbuftoosmall)); } passlen1 = MIN(passlen1, MAX_PASS_LEN); @@ -810,8 +830,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int * Ensure the plaintext passwords are in UNIX format. */ if(!doencrypt) { - dos_to_unix(smb_apasswd,True); - dos_to_unix(smb_ntpasswd,True); + pstrcpy(smb_apasswd,dos_to_unix(smb_apasswd,False)); + pstrcpy(smb_ntpasswd,dos_to_unix(smb_ntpasswd,False)); } } else { @@ -821,7 +841,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int /* * Ensure the plaintext password is in UNIX format. */ - dos_to_unix(smb_apasswd,True); + pstrcpy(smb_apasswd,dos_to_unix(smb_apasswd,False)); /* trim the password */ smb_apasslen = strlen(smb_apasswd); @@ -840,13 +860,19 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int * Incoming user and domain are in DOS codepage format. Convert * to UNIX. */ - dos_to_unix(user,True); - domain = p; - dos_to_unix(domain, True); + pstrcpy(user,dos_to_unix(user,False)); + fstrcpy(domain, dos_to_unix(p, False)); DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", domain,skip_string(p,1),skip_string(p,2))); } + /* don't allow strange characters in usernames or domains */ + alpha_strcpy(user, user, ". _-", sizeof(user)); + alpha_strcpy(domain, domain, ". _-", sizeof(domain)); + if (strstr(user, "..") || strstr(domain,"..")) { + return bad_password_error(inbuf, outbuf); + } + DEBUG(3,("sesssetupX:name=[%s]\n",user)); /* If name ends in $ then I think it's asking about whether a */ @@ -895,15 +921,23 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int pstrcpy( orig_user, user); - /* if the username exists as a domain/username pair on the unix system then use - that */ - if (!sys_getpwnam(user)) { - pstring user2; - slprintf(user2,sizeof(user2)-1,"%s%s%s", dos_to_unix(domain,False), lp_winbind_separator(), user); - if (sys_getpwnam(user2)) { - DEBUG(3,("Using unix username %s\n", user2)); - pstrcpy(user, user2); - } + /* + * Always try the "DOMAIN\user" lookup first, as this is the most + * specific case. If this fails then try the simple "user" lookup. + */ + + { + pstring dom_user; + + /* Work out who's who */ + + slprintf(dom_user, sizeof(dom_user) - 1,"%s%s%s", + dos_to_unix(domain, False), lp_winbind_separator(), user); + + if (sys_getpwnam(dom_user) != NULL) { + pstrcpy(user, dom_user); + DEBUG(3,("Using unix username %s\n", dom_user)); + } } /* @@ -1054,6 +1088,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int to a uid can get through without a password, on the same VC */ sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest); + + if (sess_vuid == -1) { + return(ERROR(ERRDOS,ERRnoaccess)); + } + SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); @@ -1840,14 +1879,15 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; - pstring fname2; int outsize = 0; int createmode; - mode_t unixmode; + mode_t unixmode = 0600; BOOL bad_path = False; files_struct *fsp; int oplock_request = CORE_OPLOCK_REQUEST(inbuf); + int tmpfd; SMB_STRUCT_STAT sbuf; + START_PROFILE(SMBctemp); createmode = SVAL(inbuf,smb_vwv0); @@ -1858,17 +1898,22 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, unix_convert(fname,conn,0,&bad_path,&sbuf); - unixmode = unix_mode(conn,createmode,fname); - - pstrcpy(fname2,(char *)smbd_mktemp(fname)); - /* This file should not exist. */ - ZERO_STRUCT(sbuf); - vfs_stat(conn,fname2,&sbuf); + tmpfd = smb_mkstemp(fname); + if (tmpfd == -1) { + END_PROFILE(SMBctemp); + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + + vfs_stat(conn,fname,&sbuf); /* Open file in dos compatibility share mode. */ - /* We should fail if file exists. */ - fsp = open_file_shared(conn,fname2,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), - (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL); + /* We should fail if file does not exist. */ + fsp = open_file_shared(conn,fname,&sbuf, + SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), + FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST, + unixmode, oplock_request, NULL, NULL); + /* close fd from smb_mkstemp() */ + close(tmpfd); if (!fsp) { @@ -1881,10 +1926,10 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(UNIXERROR(ERRDOS,ERRnoaccess)); } - outsize = set_message(outbuf,1,2 + strlen(fname2),True); + outsize = set_message(outbuf,1,2 + strlen(fname),True); SSVAL(outbuf,smb_vwv0,fsp->fnum); CVAL(smb_buf(outbuf),0) = 4; - pstrcpy(smb_buf(outbuf) + 1,fname2); + pstrcpy(smb_buf(outbuf) + 1,fname); if (oplock_request && lp_fake_oplocks(SNUM(conn))) { CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; @@ -1893,9 +1938,9 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; - DEBUG( 2, ( "created temp file %s\n", fname2 ) ); + DEBUG( 2, ( "created temp file %s\n", fname ) ); DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n", - fname2, fsp->fd, createmode, (int)unixmode ) ); + fname, fsp->fd, createmode, (int)unixmode ) ); END_PROFILE(SMBctemp); return(outsize); @@ -2154,7 +2199,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s maxcount = MIN(65535,maxcount); maxcount = MAX(mincount,maxcount); - if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) + if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { SMB_OFF_T size = fsp->size; SMB_OFF_T sizeneeded = startpos + maxcount; @@ -2251,7 +2296,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length * for a write lock. JRA. */ - if(!do_lock( fsp, conn, (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &eclass, &ecode)) { + if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &eclass, &ecode)) { if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) { /* * A blocking lock was requested. Package up @@ -2311,7 +2356,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { END_PROFILE(SMBread); return(ERROR(ERRDOS,ERRlock)); } @@ -2388,7 +2433,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt } - if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { END_PROFILE(SMBreadX); return(ERROR(ERRDOS,ERRlock)); } @@ -2449,7 +2494,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, CVAL(inbuf,smb_com) = SMBwritec; CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwritebraw); return(ERROR(ERRDOS,ERRlock)); } @@ -2472,7 +2517,8 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, CVAL(outbuf,smb_com) = SMBwritebraw; SSVALS(outbuf,smb_vwv0,-1); outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("reply_writebraw: send_smb failed.\n"); /* Now read the raw data into the buffer and write it */ if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) { @@ -2514,6 +2560,12 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, follows what WfWg does */ END_PROFILE(SMBwritebraw); if (!write_through && total_written==tcount) { + /* + * Fix for "rabbit pellet" mode, trigger an early TCP ack by + * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA. + */ + if (!send_keepalive(smbd_server_fd())) + exit_server("reply_writebraw: send of keepalive failed"); return(-1); } @@ -2544,7 +2596,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz startpos = IVAL(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwriteunlock); return(ERROR(ERRDOS,ERRlock)); } @@ -2565,7 +2617,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz return(UNIXERROR(ERRDOS,ERRnoaccess)); } - if(!do_unlock(fsp, conn, (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, &eclass, &ecode)) { + if(!do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, &eclass, &ecode)) { END_PROFILE(SMBwriteunlock); return(ERROR(eclass,ecode)); } @@ -2608,7 +2660,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d startpos = IVAL(inbuf,smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwrite); return(ERROR(ERRDOS,ERRlock)); } @@ -2657,7 +2709,9 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng BOOL write_through = BITSETW(inbuf+smb_vwv7,0); ssize_t nwritten = -1; unsigned int smb_doff = SVAL(inbuf,smb_vwv11); + unsigned int smblen = smb_len(inbuf); char *data; + BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF)); START_PROFILE(SMBwriteX); /* If it's an IPC, pass off the pipe handler. */ @@ -2670,7 +2724,11 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng CHECK_WRITE(fsp); CHECK_ERROR(fsp); - if(smb_doff > smb_len(inbuf)) { + /* Deal with possible LARGE_WRITEX */ + if (large_writeX) + numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16); + + if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) { END_PROFILE(SMBwriteX); return(ERROR(ERRDOS,ERRbadmem)); } @@ -2700,7 +2758,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng #endif /* LARGE_SMB_OFF_T */ } - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwriteX); return(ERROR(ERRDOS,ERRlock)); } @@ -2722,7 +2780,9 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng set_message(outbuf,6,0,True); SSVAL(outbuf,smb_vwv2,nwritten); - + if (large_writeX) + SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1); + if (nwritten < (ssize_t)numtowrite) { CVAL(outbuf,smb_rcls) = ERRHRD; SSVAL(outbuf,smb_err,ERRdiskfull); @@ -2983,7 +3043,7 @@ int reply_writeclose(connection_struct *conn, mtime = make_unix_date3(inbuf+smb_vwv4); data = smb_buf(inbuf) + 1; - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) { END_PROFILE(SMBwriteclose); return(ERROR(ERRDOS,ERRlock)); } @@ -3041,7 +3101,7 @@ int reply_lock(connection_struct *conn, DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", fsp->fd, fsp->fnum, (double)offset, (double)count)); - if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) { + if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &eclass, &ecode)) { if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) { /* * A blocking lock was requested. Package up @@ -3080,7 +3140,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, in count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1); offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); - if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode)) { + if(!do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, &eclass, &ecode)) { END_PROFILE(SMBunlock); return (ERROR(eclass,ecode)); } @@ -3149,7 +3209,8 @@ int reply_echo(connection_struct *conn, smb_setlen(outbuf,outsize - 4); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("reply_echo: send_smb failed.\n"); } DEBUG(3,("echo %d times\n", smb_reverb)); @@ -3177,7 +3238,7 @@ int reply_printopen(connection_struct *conn, } /* Open for exclusive use, write only. */ - fsp = print_fsp_open(conn,"dos.prn"); + fsp = print_fsp_open(conn); if (!fsp) { END_PROFILE(SMBsplopen); @@ -4195,6 +4256,18 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size } /**************************************************************************** + Get a lock pid, dealing with large count requests. +****************************************************************************/ + +uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format) +{ + if(!large_file_format) + return SVAL(data,SMB_LPID_OFFSET(data_offset)); + else + return SVAL(data,SMB_LARGE__LPID_OFFSET(data_offset)); +} + +/**************************************************************************** Get a lock count, dealing with large count requests. ****************************************************************************/ @@ -4293,6 +4366,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length, uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = 0, offset = 0; + uint16 lock_pid; int32 lock_timeout = IVAL(inbuf,smb_vwv4); int i; char *data; @@ -4316,7 +4390,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length, BOOL break_to_none = (oplocklevel == 0); DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n", - fsp->fnum, (unsigned int)oplocklevel )); + (unsigned int)oplocklevel, fsp->fnum )); /* * Make sure we have granted an exclusive or batch oplock on this file. @@ -4365,6 +4439,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); /* Data now points at the beginning of the list of smb_unlkrng structs */ for(i = 0; i < (int)num_ulocks; i++) { + lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); @@ -4376,10 +4451,10 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); return ERROR(ERRDOS,ERRnoaccess); } - DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n", - (double)offset, (double)count, fsp->fsp_name )); + DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n", + (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); - if(!do_unlock(fsp,conn,count,offset, &eclass, &ecode)) { + if(!do_unlock(fsp,conn,lock_pid,count,offset, &eclass, &ecode)) { END_PROFILE(SMBlockingX); return ERROR(eclass,ecode); } @@ -4395,6 +4470,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); of smb_lkrng structs */ for(i = 0; i < (int)num_locks; i++) { + lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); @@ -4406,10 +4482,10 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); return ERROR(ERRDOS,ERRnoaccess); } - DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n", - (double)offset, (double)count, fsp->fsp_name )); + DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s\n", + (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name )); - if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), + if(!do_lock(fsp,conn,lock_pid, count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &eclass, &ecode)) { if((ecode == ERRlock) && (lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) { /* @@ -4435,6 +4511,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); * will delete it (and we shouldn't) ..... */ for(i--; i >= 0; i--) { + lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); @@ -4446,7 +4523,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); return ERROR(ERRDOS,ERRnoaccess); } - do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); + do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2); } END_PROFILE(SMBlockingX); return ERROR(eclass,ecode); @@ -4503,7 +4580,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, tcount = maxcount; total_read = 0; - if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { END_PROFILE(SMBreadBmpx); return(ERROR(ERRDOS,ERRlock)); } @@ -4525,7 +4602,8 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length, SSVAL(outbuf,smb_vwv6,nread); SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf)); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("reply_readbmpx: send_smb failed.\n"); total_read += nread; startpos += nread; @@ -4569,7 +4647,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, not an SMBwritebmpx - set this up now so we don't forget */ CVAL(outbuf,smb_com) = SMBwritec; - if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) { + if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) { END_PROFILE(SMBwriteBmpx); return(ERROR(ERRDOS,ERRlock)); } @@ -4623,7 +4701,8 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, if (write_through && tcount==nwritten) { /* we need to send both a primary and a secondary response */ smb_setlen(outbuf,outsize - 4); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("reply_writebmpx: send_smb failed.\n"); /* now the secondary */ outsize = set_message(outbuf,1,0,True); diff --git a/source/smbd/sec_ctx.c b/source/smbd/sec_ctx.c index f604f6cce71..9ca63a0f957 100644 --- a/source/smbd/sec_ctx.c +++ b/source/smbd/sec_ctx.c @@ -109,6 +109,10 @@ static BOOL become_id(uid_t uid, gid_t gid) static void gain_root(void) { + if (non_root_mode()) { + return; + } + if (geteuid() != 0) { set_effective_uid(0); @@ -152,8 +156,10 @@ int get_current_groups(int *p_ngroups, gid_t **p_groups) return -1; } - if ((ngroups = sys_getgroups(ngroups,groups)) == -1) + if ((ngroups = sys_getgroups(ngroups,groups)) == -1) { + safe_free(groups); return -1; + } (*p_ngroups) = ngroups; (*p_groups) = groups; @@ -275,8 +281,8 @@ BOOL push_sec_ctx(void) ctx_p->uid = geteuid(); ctx_p->gid = getegid(); - DEBUG(3, ("push_sec_ctx(%d, %d) : sec_ctx_stack_ndx = %d\n", - ctx_p->uid, ctx_p->gid, sec_ctx_stack_ndx )); + DEBUG(3, ("push_sec_ctx(%u, %u) : sec_ctx_stack_ndx = %d\n", + (unsigned int)ctx_p->uid, (unsigned int)ctx_p->gid, sec_ctx_stack_ndx )); ctx_p->token = dup_nt_token(sec_ctx_stack[sec_ctx_stack_ndx-1].token); @@ -307,14 +313,15 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN /* Set the security context */ - DEBUG(3, ("setting sec ctx (%d, %d) - sec_ctx_stack_ndx = %d\n", uid, gid, sec_ctx_stack_ndx)); + DEBUG(3, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", + (unsigned int)uid, (unsigned int)gid, sec_ctx_stack_ndx)); if (ngroups) { int i; DEBUG(3, ("%d user groups: \n", ngroups)); for (i = 0; i < ngroups; i++) { - DEBUGADD(3, ("%d ", groups[i])); + DEBUGADD(3, ("%u ", (unsigned int)groups[i])); } DEBUG(3, ("\n")); @@ -413,7 +420,8 @@ BOOL pop_sec_ctx(void) current_user.groups = prev_ctx_p->groups; current_user.nt_user_token = prev_ctx_p->token; - DEBUG(3, ("pop_sec_ctx (%d, %d) - sec_ctx_stack_ndx = %d\n", geteuid(), getegid(), sec_ctx_stack_ndx)); + DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", + (unsigned int)geteuid(), (unsigned int)getegid(), sec_ctx_stack_ndx)); return True; } diff --git a/source/smbd/server.c b/source/smbd/server.c index bd98fe802fb..49cc9c8fa5c 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -208,7 +208,7 @@ max can be %d\n", num = sys_select(FD_SETSIZE,&lfds,NULL); if (num == -1 && errno == EINTR) { - extern VOLATILE SIG_ATOMIC_T reload_after_sighup; + extern VOLATILE sig_atomic_t reload_after_sighup; /* check for sighup processing */ if (reload_after_sighup) { @@ -228,7 +228,7 @@ max can be %d\n", accept on these. */ for( ; num > 0; num--) { struct sockaddr addr; - int in_addrlen = sizeof(addr); + socklen_t in_addrlen = sizeof(addr); s = -1; for(i = 0; i < num_interfaces; i++) { @@ -277,6 +277,16 @@ max can be %d\n", /* The parent doesn't need this socket */ close(smbd_server_fd()); + /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu: + Clear the closed fd info out of server_fd -- + and more importantly, out of client_fd in + util_sock.c, to avoid a possible + getpeername failure if we reopen the logs + and use %I in the filename. + */ + + smbd_set_server_fd(-1); + /* Force parent to check log size after * spawning child. Fix from * klausr@ITAP.Physik.Uni-Stuttgart.De. The @@ -356,7 +366,7 @@ BOOL reload_services(BOOL test) Catch a sighup. ****************************************************************************/ -VOLATILE SIG_ATOMIC_T reload_after_sighup = False; +VOLATILE sig_atomic_t reload_after_sighup = False; static void sig_hup(int sig) { @@ -411,16 +421,14 @@ static BOOL dump_core(void) /**************************************************************************** update the current smbd process count ****************************************************************************/ + static void decrement_smbd_process_count(void) { int total_smbds; if (lp_max_smbd_processes()) { - tdb_lock_bystring(conn_tdb_ctx(), "INFO/total_smbds"); - if ((total_smbds = tdb_fetch_int(conn_tdb_ctx(), "INFO/total_smbds")) > 0) - tdb_store_int(conn_tdb_ctx(), "INFO/total_smbds", total_smbds - 1); - - tdb_unlock_bystring(conn_tdb_ctx(), "INFO/total_smbds"); + total_smbds = 0; + tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1); } } @@ -441,12 +449,14 @@ void exit_server(char *reason) conn_close_all(); + invalidate_all_vuids(); + /* delete our entry in the connections database. */ if (lp_status(-1)) { yield_connection(NULL,"",MAXSTATUS); } - respond_to_all_remaining_local_messages(); + respond_to_all_remaining_local_messages(); decrement_smbd_process_count(); #ifdef WITH_DFS @@ -611,15 +621,7 @@ static void usage(char *pname) setluid(0); #endif - /* - * gain_root_privilege uses an assert than will cause a core - * dump if euid != 0. Ensure this is the case. - */ - - if(geteuid() != (uid_t)0) { - fprintf(stderr, "%s: Version %s : Must have effective user id of zero to run.\n", argv[0], VERSION); - exit(1); - } + sec_init(); append_log = True; diff --git a/source/smbd/service.c b/source/smbd/service.c index 394f8ae46d5..f2af4403b2a 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -108,11 +108,6 @@ int add_home_service(char *service, char *homedir) lp_add_home(new_service,iHomeService,homedir); iService = lp_servicenumber(new_service); - if ((iService != -1) && usr_p && (strstr(lp_pathname(iService),"%D") == NULL)) - DEBUG(0,("find_service: Service %s added for user %s - contains non-local (Domain) user \ -with non-domain parameterised path (%s). This may be cause the wrong directory to be seen.\n", - new_service, service, lp_pathname(iService) )); - return iService; } @@ -530,39 +525,12 @@ connection_struct *make_connection(char *service,char *user,char *password, int } /* Initialise VFS function pointers */ -#if WITH_VFS - if (*lp_vfsobj(SNUM(conn))) { - -#ifdef HAVE_LIBDL - - /* Loadable object file */ - - if (!vfs_init_custom(conn)) { - DEBUG(0, ("vfs_init failed\n")); - conn_free(conn); - return NULL; - } -#else /* HAVE_LIBDL */ - DEBUG(0, ("No libdl present - cannot use VFS objects\n")); - conn_free(conn); - return NULL; -#endif /* HAVE_LIBDL */ - - } else { - - /* Normal share - initialise with disk access functions */ - - vfs_init_default(conn); + if (!vfs_init(conn)) { + DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn)))); + conn_free(conn); + return NULL; } -#else /* WITH_VFS */ - - /* Normal share - initialise with disk access functions */ - - vfs_init_default(conn); - -#endif /* WITH_VFS */ - /* execute any "root preexec = " line */ if (*lp_rootpreexec(SNUM(conn))) { pstring cmd; @@ -712,3 +680,5 @@ void close_cnum(connection_struct *conn, uint16 vuid) } conn_free(conn); } + + diff --git a/source/smbd/ssl.c b/source/smbd/ssl.c index 65d6532d486..dff5f34d5dd 100644 --- a/source/smbd/ssl.c +++ b/source/smbd/ssl.c @@ -255,11 +255,15 @@ char *reqHosts, *resignHosts; if(msg_type != 0x81){ /* first packet must be a session request */ DEBUG( 0, ( "Client %s did not use session setup; access denied\n", client_addr() ) ); - send_smb(fd, (char *)buf); + if (!send_smb(fd, (char *)buf)) + DEBUG(0, ("sslutil_negotiate_ssl: send_smb failed.\n")); return -1; } buf[4] = 0x8e; /* negative session response: use SSL */ - send_smb(fd, (char *)buf); + if (!send_smb(fd, (char *)buf)) { + DEBUG(0,("sslutil_negotiate_ssl: send_smb failed.\n")); + return -1; + } if(sslutil_accept(fd) != 0){ DEBUG( 0, ( "Client %s failed SSL negotiation!\n", client_addr() ) ); return -1; diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c index 8200c277b32..65a48300164 100644 --- a/source/smbd/statcache.c +++ b/source/smbd/statcache.c @@ -221,11 +221,11 @@ BOOL reset_stat_cache( void ) static BOOL initialised; if (!lp_stat_cache()) return True; - if (!initialised) { - initialised = True; - return hash_table_init( &stat_cache, INIT_STAT_CACHE_SIZE, (compare_function)(strcmp)); + if (initialised) { + hash_clear(&stat_cache); } - hash_clear(&stat_cache); - return hash_table_init( &stat_cache, INIT_STAT_CACHE_SIZE, (compare_function)(strcmp)); + initialised = hash_table_init( &stat_cache, INIT_STAT_CACHE_SIZE, + (compare_function)(strcmp)); + return initialised; } /* reset_stat_cache */ diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 05a02238957..5f0652e5780 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -65,7 +65,8 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params, the empty packet */ if(params_to_send == 0 && data_to_send == 0) { - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_trans2_replies: send_smb failed.\n"); return 0; } @@ -160,7 +161,8 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params, params_to_send, data_to_send, paramsize, datasize)); /* Send the packet */ - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_trans2_replies: send_smb failed.\n"); pp += params_sent_thistime; pd += data_sent_thistime; @@ -432,6 +434,13 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, mdate = sbuf.st_mtime; adate = sbuf.st_atime; cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + + if (lp_dos_filetime_resolution(SNUM(conn))) { + cdate &= ~1; + mdate &= ~1; + adate &= ~1; + } + if(mode & aDIR) size = 0; @@ -1173,9 +1182,10 @@ static int call_trans2qfsinfo(connection_struct *conn, (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */ #if 0 /* Old code. JRA. */ SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */ + SIVAL(pdata,0,0x700FF); #endif /* Old code. */ - SIVAL(pdata,4,128); /* Max filename component length */ + SIVAL(pdata,4,255); /* Max filename component length */ fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False); SIVAL(pdata,8,fstype_len); data_len = 12 + fstype_len; @@ -1303,6 +1313,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, SMB_OFF_T pos = 0; BOOL bad_path = False; BOOL delete_pending = False; + time_t c_time; if (tran_call == TRANSACT2_QFILEINFO) { files_struct *fsp = file_fsp(params,0); @@ -1410,12 +1421,21 @@ static int call_trans2qfilepathinfo(connection_struct *conn, memset((char *)pdata,'\0',data_size); + c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + + if (lp_dos_filetime_resolution(SNUM(conn))) { + c_time &= ~1; + sbuf.st_atime &= ~1; + sbuf.st_mtime &= ~1; + sbuf.st_mtime &= ~1; + } + switch (info_level) { case SMB_INFO_STANDARD: case SMB_INFO_QUERY_EA_SIZE: data_size = (info_level==1?22:26); - put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); + put_dos_date2(pdata,l1_fdateCreation,c_time); put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ SIVAL(pdata,l1_cbFile,(uint32)size); @@ -1426,7 +1446,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, case SMB_INFO_QUERY_EAS_FROM_LIST: data_size = 24; - put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); + put_dos_date2(pdata,0,c_time); put_dos_date2(pdata,4,sbuf.st_atime); put_dos_date2(pdata,8,sbuf.st_mtime); SIVAL(pdata,12,(uint32)size); @@ -1443,8 +1463,15 @@ static int call_trans2qfilepathinfo(connection_struct *conn, return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */ case SMB_QUERY_FILE_BASIC_INFO: - data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ - put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); + case 1004: + + if (info_level == SMB_QUERY_FILE_BASIC_INFO) + data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ + else { + data_size = 40; + SIVAL(pdata,36,0); + } + put_long_date(pdata,c_time); put_long_date(pdata+8,sbuf.st_atime); put_long_date(pdata+16,sbuf.st_mtime); /* write time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */ @@ -1452,7 +1479,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, DEBUG(5,("SMB_QFBI - ")); { - time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + time_t create_time = c_time; DEBUG(5,("create: %s ", ctime(&create_time))); } DEBUG(5,("access: %s ", ctime(&sbuf.st_atime))); @@ -1518,7 +1545,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, break; case SMB_QUERY_FILE_ALL_INFO: - put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); + put_long_date(pdata,c_time); put_long_date(pdata+8,sbuf.st_atime); put_long_date(pdata+16,sbuf.st_mtime); /* write time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */ @@ -1549,6 +1576,144 @@ static int call_trans2qfilepathinfo(connection_struct *conn, data_size = PTR_DIFF(pdata,(*ppdata)); break; + /* + * Windows 2000 completely undocumented new SMB info levels. + * Thanks Microsoft.... sure you're working on making this + * protocol a standard.... sure you are... :-). + * Lying rat-bastards. JRA. + */ + + case 1005: + SIVAL(pdata,0,mode); + SIVAL(pdata,4,0); /* ??? */ + SOFF_T(pdata,8,size); + SIVAL(pdata,16,1); /* ??? */ + SIVAL(pdata,20,0); /* ??? */ + data_size = 24; + break; + + case 1006: + SIVAL(pdata,0,0x907); /* ??? */ + SIVAL(pdata,4,0x690000); /* ??? */ + data_size = 8; + break; + + case 1007: + SIVAL(pdata,0,0); /* ??? */ + data_size = 4; + break; + + case 1008: + SIVAL(pdata,0,0x12019F); /* ??? */ + data_size = 4; + break; + + case 1009: + /* Pathname with leading '\'. */ + { + pstring new_fname; + size_t byte_len; + + pstrcpy(new_fname, "\\"); + pstrcat(new_fname, fname); + byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False); + SIVAL(pdata,0,byte_len); + data_size = 4 + byte_len; + break; + } + + case 1014: + SIVAL(pdata,0,0); /* ??? */ + SIVAL(pdata,4,0); /* ??? */ + data_size = 8; + break; + + case 1016: + SIVAL(pdata,0,0); /* ??? */ + data_size = 4; + break; + + case 1017: + SIVAL(pdata,0,0); /* ??? */ + data_size = 4; + break; + +#if 0 + /* Not yet finished... JRA */ + case 1018: + { + pstring new_fname; + size_t byte_len; + + put_long_date(pdata,c_time); + put_long_date(pdata+8,sbuf.st_atime); + put_long_date(pdata+16,sbuf.st_mtime); /* write time */ + put_long_date(pdata+24,sbuf.st_mtime); /* change time */ + SIVAL(pdata,32,mode); + SIVAL(pdata,36,0); /* ??? */ + SIVAL(pdata,40,0x20); /* ??? */ + SIVAL(pdata,44,0); /* ??? */ + SOFF_T(pdata,48,size); + SIVAL(pdata,56,0x1); /* ??? */ + SIVAL(pdata,60,0); /* ??? */ + SIVAL(pdata,64,0); /* ??? */ + SIVAL(pdata,68,length); /* Following string length in bytes. */ + dos_PutUniCode(pdata+72,,False); + break; + } +#endif + + case 1021: + /* Last component of pathname. */ + { + size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False); + SIVAL(pdata,0,byte_len); + data_size = 4 + byte_len; + break; + } + + case 1022: + { + size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False); + SIVAL(pdata,0,0); /* ??? */ + SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */ + SOFF_T(pdata,8,size); + SIVAL(pdata,16,0x20); /* ??? */ + SIVAL(pdata,20,0); /* ??? */ + data_size = 24 + byte_len; + break; + } + + case 1028: + SOFF_T(pdata,0,size); + SIVAL(pdata,8,0); /* ??? */ + SIVAL(pdata,12,0); /* ??? */ + data_size = 16; + break; + + case 1034: + put_long_date(pdata,c_time); + put_long_date(pdata+8,sbuf.st_atime); + put_long_date(pdata+16,sbuf.st_mtime); /* write time */ + put_long_date(pdata+24,sbuf.st_mtime); /* change time */ + SIVAL(pdata,32,0x20); /* ??? */ + SIVAL(pdata,36,0); /* ??? */ + SOFF_T(pdata,40,size); + SIVAL(pdata,48,mode); + SIVAL(pdata,52,0); /* ??? */ + data_size = 56; + break; + + case 1035: + SIVAL(pdata,0,mode); + SIVAL(pdata,4,0); + data_size = 8; + break; + + /* + * End new completely undocumented info levels... JRA. + */ + #if 0 /* NT4 server just returns "invalid query" to this - if we try to answer it then NTws gets a BSOD! (tridge) */ @@ -1731,6 +1896,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, break; case SMB_SET_FILE_BASIC_INFO: + case 1004: { /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */ time_t write_time; @@ -1752,14 +1918,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, ? changed_time : write_time); -#if 0 /* Needs more testing... */ - /* Test from Luke to prevent Win95 from - setting incorrect values here. - */ - if (tvs.actime < tvs.modtime) - return(ERROR(ERRDOS,ERRnoaccess)); -#endif /* Needs more testing... */ - /* attributes */ mode = IVAL(pdata,32); break; @@ -1770,6 +1928,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn, * to mean truncate the file. JRA. */ + case 1019: + case 1020: case SMB_SET_FILE_ALLOCATION_INFO: { SMB_OFF_T newsize = IVAL(pdata,0); @@ -1903,7 +2063,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, DEBUG(6,("mode: %x\n" , mode)); if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) || - (info_level == SMB_SET_FILE_ALLOCATION_INFO))) { + (info_level == SMB_SET_FILE_ALLOCATION_INFO) || + (info_level == 1019) || + (info_level == 1020))) { /* * Only do this test if we are not explicitly * changing the size of a file. @@ -2348,7 +2510,8 @@ int reply_trans2(connection_struct *conn, /* We need to send an interim response then receive the rest of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("reply_trans2: send_smb failed.\n"); while (num_data_sofar < total_data || num_params_sofar < total_params) { diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c index da8484e14ee..058b02b5ac1 100644 --- a/source/smbd/vfs-wrap.c +++ b/source/smbd/vfs-wrap.c @@ -479,33 +479,34 @@ int vfswrap_utime(connection_struct *conn, char *path, struct utimbuf *times) int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) { int result = -1; - START_PROFILE(syscall_ftruncate); - -#ifdef HAVE_FTRUNCATE_EXTEND - result = sys_ftruncate(fd, len); - END_PROFILE(syscall_ftruncate); - return result; -#else - - /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot - extend a file with ftruncate. Provide alternate implementation - for this */ - struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops; SMB_STRUCT_STAT st; char c = 0; SMB_OFF_T currpos; - currpos = vfs_ops->lseek(fsp, (SMB_OFF_T)0, SEEK_CUR); - if(currpos == -1) { + START_PROFILE(syscall_ftruncate); + + /* we used to just check HAVE_FTRUNCATE_EXTEND and only use + sys_ftruncate if the system supports it. Then I discovered that + you can have some filesystems that support ftruncate + expansion and some that don't! On Linux fat can't do + ftruncate extend but ext2 can. */ + result = sys_ftruncate(fd, len); + if (result == 0) goto done; + + /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot + extend a file with ftruncate. Provide alternate implementation + for this */ + currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR); + if (currpos == -1) { goto done; } - /* Do an fstat to see if the file is longer than - the requested size (call ftruncate), - or shorter, in which case seek to len - 1 and write 1 - byte of zero */ - if(vfs_ops->fstat(fsp, &st)<0) { + /* Do an fstat to see if the file is longer than the requested + size in which case the ftruncate above should have + succeeded or shorter, in which case seek to len - 1 and + write 1 byte of zero */ + if (vfs_ops->fstat(fsp, fd, &st) < 0) { goto done; } @@ -516,35 +517,33 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len) } #endif - if(st.st_size == len) { + if (st.st_size == len) { result = 0; goto done; } - if(st.st_size > len) { - /* Yes this is *deliberately* sys_ftruncate ! JRA */ - result = sys_ftruncate(fd, len); + if (st.st_size > len) { + /* the sys_ftruncate should have worked */ goto done; } - if(vfs_ops->lseek(fsp, len-1, SEEK_SET) != len -1) { + if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1) { goto done; } - if(vfs_ops->write(fsp, &c, 1)!=1) { + if (vfs_ops->write(fsp, fd, &c, 1)!=1) { goto done; } /* Seek to where we were */ - if(vfs_ops->lseek(fsp, currpos, SEEK_SET) != currpos) { + if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos) { goto done; } + result = 0; done: - END_PROFILE(syscall_ftruncate); - return result; -#endif - + END_PROFILE(syscall_ftruncate); + return result; } BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) @@ -558,6 +557,38 @@ BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T return result; } +int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath) +{ + int result; + + START_PROFILE(syscall_symlink); + +#ifdef VFS_CHECK_NULL + if ((oldpath == NULL) || (newpath == NULL)) + smb_panic("NULL pointer passed to vfswrap_symlink()\n"); +#endif + + result = sys_symlink(oldpath, newpath); + END_PROFILE(syscall_symlink); + return result; +} + +int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz) +{ + int result; + + START_PROFILE(syscall_readlink); + +#ifdef VFS_CHECK_NULL + if ((path == NULL) || (buf == NULL)) + smb_panic("NULL pointer passed to vfswrap_readlink()\n"); +#endif + + result = sys_readlink(path, buf, bufsiz); + END_PROFILE(syscall_readlink); + return result; +} + size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc) { return get_nt_acl(fsp, ppdesc); diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c index 713d58cdc8c..ac00d00e9e1 100644 --- a/source/smbd/vfs.c +++ b/source/smbd/vfs.c @@ -72,6 +72,9 @@ struct vfs_ops default_vfs_ops = { vfswrap_utime, vfswrap_ftruncate, vfswrap_lock, + vfswrap_symlink, + vfswrap_readlink, + vfswrap_fget_nt_acl, vfswrap_get_nt_acl, vfswrap_fset_nt_acl, @@ -89,7 +92,8 @@ struct vfs_ops default_vfs_ops = { /**************************************************************************** initialise default vfs hooks ****************************************************************************/ -int vfs_init_default(connection_struct *conn) + +static BOOL vfs_init_default(connection_struct *conn) { DEBUG(3, ("Initialising default vfs hooks\n")); @@ -102,7 +106,7 @@ int vfs_init_default(connection_struct *conn) ****************************************************************************/ #ifdef HAVE_LIBDL -BOOL vfs_init_custom(connection_struct *conn) +static BOOL vfs_init_custom(connection_struct *conn) { int vfs_version = -1; struct vfs_ops *ops, *(*init_fptr)(int *); @@ -146,145 +150,146 @@ BOOL vfs_init_custom(connection_struct *conn) memcpy(&conn->vfs_ops, ops, sizeof(struct vfs_ops)); - if (conn->vfs_ops.connect == NULL) { - conn->vfs_ops.connect = default_vfs_ops.connect; - } + if (conn->vfs_ops.connect == NULL) + conn->vfs_ops.connect = default_vfs_ops.connect; - if (conn->vfs_ops.disconnect == NULL) { - conn->vfs_ops.disconnect = default_vfs_ops.disconnect; - } + if (conn->vfs_ops.disconnect == NULL) + conn->vfs_ops.disconnect = default_vfs_ops.disconnect; - if (conn->vfs_ops.disk_free == NULL) { - conn->vfs_ops.disk_free = default_vfs_ops.disk_free; - } + if (conn->vfs_ops.disk_free == NULL) + conn->vfs_ops.disk_free = default_vfs_ops.disk_free; - if (conn->vfs_ops.opendir == NULL) { - conn->vfs_ops.opendir = default_vfs_ops.opendir; - } + if (conn->vfs_ops.opendir == NULL) + conn->vfs_ops.opendir = default_vfs_ops.opendir; - if (conn->vfs_ops.readdir == NULL) { - conn->vfs_ops.readdir = default_vfs_ops.readdir; - } + if (conn->vfs_ops.readdir == NULL) + conn->vfs_ops.readdir = default_vfs_ops.readdir; - if (conn->vfs_ops.mkdir == NULL) { - conn->vfs_ops.mkdir = default_vfs_ops.mkdir; - } + if (conn->vfs_ops.mkdir == NULL) + conn->vfs_ops.mkdir = default_vfs_ops.mkdir; - if (conn->vfs_ops.rmdir == NULL) { - conn->vfs_ops.rmdir = default_vfs_ops.rmdir; - } + if (conn->vfs_ops.rmdir == NULL) + conn->vfs_ops.rmdir = default_vfs_ops.rmdir; - if (conn->vfs_ops.closedir == NULL) { - conn->vfs_ops.closedir = default_vfs_ops.closedir; - } + if (conn->vfs_ops.closedir == NULL) + conn->vfs_ops.closedir = default_vfs_ops.closedir; - if (conn->vfs_ops.open == NULL) { - conn->vfs_ops.open = default_vfs_ops.open; - } + if (conn->vfs_ops.open == NULL) + conn->vfs_ops.open = default_vfs_ops.open; - if (conn->vfs_ops.close == NULL) { - conn->vfs_ops.close = default_vfs_ops.close; - } + if (conn->vfs_ops.close == NULL) + conn->vfs_ops.close = default_vfs_ops.close; - if (conn->vfs_ops.read == NULL) { - conn->vfs_ops.read = default_vfs_ops.read; - } + if (conn->vfs_ops.read == NULL) + conn->vfs_ops.read = default_vfs_ops.read; - if (conn->vfs_ops.write == NULL) { - conn->vfs_ops.write = default_vfs_ops.write; - } + if (conn->vfs_ops.write == NULL) + conn->vfs_ops.write = default_vfs_ops.write; - if (conn->vfs_ops.lseek == NULL) { - conn->vfs_ops.lseek = default_vfs_ops.lseek; - } + if (conn->vfs_ops.lseek == NULL) + conn->vfs_ops.lseek = default_vfs_ops.lseek; - if (conn->vfs_ops.rename == NULL) { - conn->vfs_ops.rename = default_vfs_ops.rename; - } + if (conn->vfs_ops.rename == NULL) + conn->vfs_ops.rename = default_vfs_ops.rename; - if (conn->vfs_ops.fsync == NULL) { - conn->vfs_ops.fsync = default_vfs_ops.fsync; - } + if (conn->vfs_ops.fsync == NULL) + conn->vfs_ops.fsync = default_vfs_ops.fsync; - if (conn->vfs_ops.stat == NULL) { - conn->vfs_ops.stat = default_vfs_ops.stat; - } + if (conn->vfs_ops.stat == NULL) + conn->vfs_ops.stat = default_vfs_ops.stat; - if (conn->vfs_ops.fstat == NULL) { - conn->vfs_ops.fstat = default_vfs_ops.fstat; - } + if (conn->vfs_ops.fstat == NULL) + conn->vfs_ops.fstat = default_vfs_ops.fstat; - if (conn->vfs_ops.lstat == NULL) { - conn->vfs_ops.lstat = default_vfs_ops.lstat; - } + if (conn->vfs_ops.lstat == NULL) + conn->vfs_ops.lstat = default_vfs_ops.lstat; - if (conn->vfs_ops.unlink == NULL) { - conn->vfs_ops.unlink = default_vfs_ops.unlink; - } + if (conn->vfs_ops.unlink == NULL) + conn->vfs_ops.unlink = default_vfs_ops.unlink; - if (conn->vfs_ops.chmod == NULL) { - conn->vfs_ops.chmod = default_vfs_ops.chmod; - } + if (conn->vfs_ops.chmod == NULL) + conn->vfs_ops.chmod = default_vfs_ops.chmod; - if (conn->vfs_ops.fchmod == NULL) { - conn->vfs_ops.fchmod = default_vfs_ops.fchmod; - } + if (conn->vfs_ops.fchmod == NULL) + conn->vfs_ops.fchmod = default_vfs_ops.fchmod; - if (conn->vfs_ops.chown == NULL) { - conn->vfs_ops.chown = default_vfs_ops.chown; - } + if (conn->vfs_ops.chown == NULL) + conn->vfs_ops.chown = default_vfs_ops.chown; - if (conn->vfs_ops.fchown == NULL) { - conn->vfs_ops.fchown = default_vfs_ops.fchown; - } + if (conn->vfs_ops.fchown == NULL) + conn->vfs_ops.fchown = default_vfs_ops.fchown; - if (conn->vfs_ops.chdir == NULL) { - conn->vfs_ops.chdir = default_vfs_ops.chdir; - } + if (conn->vfs_ops.chdir == NULL) + conn->vfs_ops.chdir = default_vfs_ops.chdir; - if (conn->vfs_ops.getwd == NULL) { - conn->vfs_ops.getwd = default_vfs_ops.getwd; - } + if (conn->vfs_ops.getwd == NULL) + conn->vfs_ops.getwd = default_vfs_ops.getwd; - if (conn->vfs_ops.utime == NULL) { - conn->vfs_ops.utime = default_vfs_ops.utime; - } + if (conn->vfs_ops.utime == NULL) + conn->vfs_ops.utime = default_vfs_ops.utime; - if (conn->vfs_ops.ftruncate == NULL) { - conn->vfs_ops.ftruncate = default_vfs_ops.ftruncate; - } + if (conn->vfs_ops.ftruncate == NULL) + conn->vfs_ops.ftruncate = default_vfs_ops.ftruncate; - if (conn->vfs_ops.lock == NULL) { - conn->vfs_ops.lock = default_vfs_ops.lock; - } + if (conn->vfs_ops.lock == NULL) + conn->vfs_ops.lock = default_vfs_ops.lock; - if (conn->vfs_ops.fget_nt_acl == NULL) { - conn->vfs_ops.fget_nt_acl = default_vfs_ops.fget_nt_acl; - } + if (conn->vfs_ops.symlink == NULL) + conn->vfs_ops.symlink = default_vfs_ops.symlink; - if (conn->vfs_ops.get_nt_acl == NULL) { - conn->vfs_ops.get_nt_acl = default_vfs_ops.get_nt_acl; - } + if (conn->vfs_ops.readlink == NULL) + conn->vfs_ops.readlink = default_vfs_ops.readlink; - if (conn->vfs_ops.fset_nt_acl == NULL) { - conn->vfs_ops.fset_nt_acl = default_vfs_ops.fset_nt_acl; - } + if (conn->vfs_ops.fget_nt_acl == NULL) + conn->vfs_ops.fget_nt_acl = default_vfs_ops.fget_nt_acl; - if (conn->vfs_ops.set_nt_acl == NULL) { - conn->vfs_ops.set_nt_acl = default_vfs_ops.set_nt_acl; - } + if (conn->vfs_ops.get_nt_acl == NULL) + conn->vfs_ops.get_nt_acl = default_vfs_ops.get_nt_acl; - if (conn->vfs_ops.chmod_acl == NULL) { - conn->vfs_ops.chmod_acl = default_vfs_ops.chmod_acl; - } + if (conn->vfs_ops.fset_nt_acl == NULL) + conn->vfs_ops.fset_nt_acl = default_vfs_ops.fset_nt_acl; + + if (conn->vfs_ops.set_nt_acl == NULL) + conn->vfs_ops.set_nt_acl = default_vfs_ops.set_nt_acl; + + if (conn->vfs_ops.chmod_acl == NULL) + conn->vfs_ops.chmod_acl = default_vfs_ops.chmod_acl; + + if (conn->vfs_ops.fchmod_acl == NULL) + conn->vfs_ops.fchmod_acl = default_vfs_ops.fchmod_acl; - if (conn->vfs_ops.fchmod_acl == NULL) { - conn->vfs_ops.fchmod_acl = default_vfs_ops.fchmod_acl; - } return True; } #endif +/***************************************************************** + Generic VFS init. +******************************************************************/ + +BOOL vfs_init(connection_struct *conn) +{ + if (*lp_vfsobj(SNUM(conn))) { +#ifdef HAVE_LIBDL + + /* Loadable object file */ + + if (!vfs_init_custom(conn)) { + DEBUG(0, ("vfs_init: vfs_init_custom failed\n")); + return False; + } + + return True; +#else + DEBUG(0, ("vfs_init: No libdl present - cannot use VFS objects\n")); + return False; +#endif + } + + /* Normal share - initialise with disk access functions */ + + return vfs_init_default(conn); +} + /******************************************************************* Check if directory exists. ********************************************************************/ diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c index 91009af1c58..7ee2d9af261 100644 --- a/source/smbwrapper/smbw.c +++ b/source/smbwrapper/smbw.c @@ -281,6 +281,7 @@ static char *smbw_find_workgroup(void) if (name_status_find(0x1d, ip_list[i], name)) { slprintf(server, sizeof(server), "%s#1D", name); if (smbw_server(server, "IPC$")) { + smbw_setshared("WORKGROUP", name); free(ip_list); return name; } diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c index 15977de8b77..1600d65a9ef 100644 --- a/source/smbwrapper/smbw_dir.c +++ b/source/smbwrapper/smbw_dir.c @@ -78,7 +78,7 @@ static struct smbw_dir *cur_dir; /***************************************************** add a entry to a directory listing *******************************************************/ -static void smbw_dir_add(struct file_info *finfo, const char *mask) +static void smbw_dir_add(struct file_info *finfo, const char *mask, void *state) { DEBUG(5,("%s\n", finfo->name)); @@ -101,7 +101,7 @@ static void smbw_dir_add(struct file_info *finfo, const char *mask) add a entry to a directory listing *******************************************************/ static void smbw_share_add(const char *share, uint32 type, - const char *comment) + const char *comment, void *state) { struct file_info finfo; @@ -112,7 +112,7 @@ static void smbw_share_add(const char *share, uint32 type, pstrcpy(finfo.name, share); finfo.mode = aRONLY | aDIR; - smbw_dir_add(&finfo, NULL); + smbw_dir_add(&finfo, NULL, NULL); } @@ -120,7 +120,7 @@ static void smbw_share_add(const char *share, uint32 type, add a server to a directory listing *******************************************************/ static void smbw_server_add(const char *name, uint32 type, - const char *comment) + const char *comment, void *state) { struct file_info finfo; @@ -129,7 +129,7 @@ static void smbw_server_add(const char *name, uint32 type, pstrcpy(finfo.name, name); finfo.mode = aRONLY | aDIR; - smbw_dir_add(&finfo, NULL); + smbw_dir_add(&finfo, NULL, NULL); } @@ -151,7 +151,7 @@ static void smbw_printjob_add(struct print_job_info *job) finfo.mode = aRONLY; finfo.size = job->size; - smbw_dir_add(&finfo, NULL); + smbw_dir_add(&finfo, NULL, NULL); } @@ -202,30 +202,30 @@ int smbw_dir_open(const char *fname) if ((p=strstr(srv->server_name,"#01"))) { *p = 0; - smbw_server_add(".",0,""); - smbw_server_add("..",0,""); + smbw_server_add(".",0,"",NULL); + smbw_server_add("..",0,"",NULL); cli_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_DOMAIN_ENUM, - smbw_server_add); + smbw_server_add,NULL); *p = '#'; } else if ((p=strstr(srv->server_name,"#1D"))) { DEBUG(4,("doing NetServerEnum\n")); *p = 0; - smbw_server_add(".",0,""); - smbw_server_add("..",0,""); + smbw_server_add(".",0,"",NULL); + smbw_server_add("..",0,"",NULL); cli_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL, - smbw_server_add); + smbw_server_add,NULL); *p = '#'; } else if (strcmp(srv->cli.dev,"IPC") == 0) { DEBUG(4,("doing NetShareEnum\n")); - smbw_share_add(".",0,""); - smbw_share_add("..",0,""); - if (cli_RNetShareEnum(&srv->cli, smbw_share_add) < 0) { + smbw_share_add(".",0,"",NULL); + smbw_share_add("..",0,"",NULL); + if (cli_RNetShareEnum(&srv->cli, smbw_share_add,NULL) < 0) { errno = smbw_errno(&srv->cli); goto failed; } } else if (strncmp(srv->cli.dev,"LPT",3) == 0) { - smbw_share_add(".",0,""); - smbw_share_add("..",0,""); + smbw_share_add(".",0,"",NULL); + smbw_share_add("..",0,"",NULL); if (cli_print_queue(&srv->cli, smbw_printjob_add) < 0) { errno = smbw_errno(&srv->cli); goto failed; @@ -233,11 +233,11 @@ int smbw_dir_open(const char *fname) } else { #if 0 if (strcmp(path,"\\") == 0) { - smbw_share_add(".",0,""); - smbw_share_add("..",0,""); + smbw_share_add(".",0,"",NULL); + smbw_share_add("..",0,"",NULL); } #endif - if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR, smbw_dir_add) < 0) { + if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR, smbw_dir_add,NULL) < 0) { errno = smbw_errno(&srv->cli); goto failed; } diff --git a/source/tdb/Makefile b/source/tdb/Makefile index 01de7d244b6..5945469737c 100644 --- a/source/tdb/Makefile +++ b/source/tdb/Makefile @@ -2,20 +2,22 @@ # Makefile for tdb directory # -CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1 +CFLAGS = -DSTANDALONE -DTDB_DEBUG -O2 -g -DHAVE_MMAP=1 CC = gcc + PROGS = tdbtest tdbtool tdbtorture +TDB_OBJ = tdb.o spinlock.o default: $(PROGS) -tdbtest: tdbtest.o tdb.o spinlock.o - $(CC) $(CFLAGS) -o tdbtest tdbtest.o tdb.o spinlock.o -lgdbm +tdbtest: tdbtest.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbtest tdbtest.o $(TDB_OBJ) -lgdbm -tdbtool: tdbtool.o tdb.o spinlock.o - $(CC) $(CFLAGS) -o tdbtool tdbtool.o tdb.o spinlock.o +tdbtool: tdbtool.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbtool tdbtool.o $(TDB_OBJ) -tdbtorture: tdbtorture.o tdb.o - $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o tdb.o spinlock.o +tdbtorture: tdbtorture.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o $(TDB_OBJ) clean: rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c index b1335728ab5..c3ded6368b7 100644 --- a/source/tdb/tdb.c +++ b/source/tdb/tdb.c @@ -56,6 +56,7 @@ #define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off)) +#define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0) /* lock offsets */ #define GLOBAL_LOCK 0 @@ -65,30 +66,45 @@ #define MAP_FILE 0 #endif +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + #define BUCKET(hash) ((hash) % tdb->header.hash_size) TDB_DATA tdb_null; /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ static TDB_CONTEXT *tdbs = NULL; -static void *tdb_munmap(void *ptr, tdb_len size) +static void tdb_munmap(TDB_CONTEXT *tdb) { #ifdef HAVE_MMAP - munmap(ptr, size); + if (tdb->map_ptr) munmap(tdb->map_ptr, tdb->map_size); #endif - return NULL; + tdb->map_ptr = NULL; } -static void *tdb_mmap(tdb_len size, int read_only, int fd) +static void tdb_mmap(TDB_CONTEXT *tdb) { - void *ret = NULL; #ifdef HAVE_MMAP - ret = mmap(NULL, size, PROT_READ | (read_only ? 0 : PROT_WRITE), MAP_SHARED|MAP_FILE, fd, 0); - - if (ret == (void *)-1) - ret = NULL; + if (!(tdb->flags & TDB_NOMMAP)) { + tdb->map_ptr = mmap(NULL, tdb->map_size, + PROT_READ|(tdb->read_only? 0:PROT_WRITE), + MAP_SHARED|MAP_FILE, tdb->fd, 0); + + /* + * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! + */ + + if (tdb->map_ptr == MAP_FAILED) { + tdb->map_ptr = NULL; + TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n", + tdb->map_size, strerror(errno))); + } + } +#else + tdb->map_ptr = NULL; #endif - return ret; } /* Endian conversion: we only ever deal with 4 byte quantities */ @@ -124,7 +140,7 @@ struct list_struct { /* a byte range locking function - return 0 on success this functions locks/unlocks 1 byte at the specified offset */ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, - int rw_type, int lck_type) + int rw_type, int lck_type, int probe) { struct flock fl; @@ -137,23 +153,40 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, fl.l_len = 1; fl.l_pid = 0; - if (fcntl(tdb->fd,lck_type,&fl)) return TDB_ERRCODE(TDB_ERR_LOCK, -1); + if (fcntl(tdb->fd,lck_type,&fl)) { + if (!probe) { + TDB_LOG((tdb, 5,"tdb_brlock failed at offset %d rw_type=%d lck_type=%d\n", + offset, rw_type, lck_type)); + } + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } return 0; } /* lock a list in the database. list -1 is the alloc list */ static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) { - if (list < -1 || list >= (int)tdb->header.hash_size) return -1; + if (list < -1 || list >= (int)tdb->header.hash_size) { + TDB_LOG((tdb, 0,"tdb_lock: invalid list %d for ltype=%d\n", + list, ltype)); + return -1; + } if (tdb->flags & TDB_NOLOCK) return 0; /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ if (tdb->locked[list+1].count == 0) { if (tdb->header.rwlocks) { - if (tdb_spinlock(tdb, list, ltype)) return -1; - } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW)) + if (tdb_spinlock(tdb, list, ltype)) { + TDB_LOG((tdb, 0, "tdb_lock spinlock on list ltype=%d\n", + list, ltype)); + return -1; + } + } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 0)) { + TDB_LOG((tdb, 0,"tdb_lock failed on list %d ltype=%d (%s)\n", + list, ltype, strerror(errno))); return -1; + } tdb->locked[list+1].ltype = ltype; } tdb->locked[list+1].count++; @@ -172,7 +205,7 @@ static void tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) if (tdb->locked[list+1].count == 1) { /* Down to last nested lock: unlock underneath */ if (tdb->header.rwlocks) tdb_spinunlock(tdb, list, ltype); - else tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW); + else tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0); } tdb->locked[list+1].count--; } @@ -192,45 +225,58 @@ static u32 tdb_hash(TDB_DATA *key) /* check for an out of bounds access - if it is out of bounds then see if the database has been expanded by someone else and expand - if necessary */ -static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset) + if necessary + note that "len" is the minimum length needed for the db +*/ +static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe) { struct stat st; - if (offset <= tdb->map_size) return 0; + if (len <= tdb->map_size) return 0; if (tdb->flags & TDB_INTERNAL) return 0; fstat(tdb->fd, &st); - if (st.st_size <= (size_t)offset) return TDB_ERRCODE(TDB_ERR_IO, -1); + if (st.st_size < (size_t)len) { + if (!probe) { + TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n", + (int)len, (int)st.st_size)); + } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } /* Unmap, update size, remap */ - if (tdb->map_ptr) tdb->map_ptr=tdb_munmap(tdb->map_ptr, tdb->map_size); + tdb_munmap(tdb); tdb->map_size = st.st_size; - if (!(tdb->flags & TDB_NOMMAP)) - tdb->map_ptr = tdb_mmap(tdb->map_size, tdb->read_only,tdb->fd); + tdb_mmap(tdb); return 0; } /* write a lump of data at a specified offset */ static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len) { - if (tdb_oob(tdb, off + len) != 0) return -1; + if (tdb_oob(tdb, off + len, 0) != 0) return -1; if (tdb->map_ptr) memcpy(off + (char *)tdb->map_ptr, buf, len); else if (lseek(tdb->fd, off, SEEK_SET) != off - || write(tdb->fd, buf, len) != (ssize_t)len) + || write(tdb->fd, buf, len) != (ssize_t)len) { + TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n", + off, len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_IO, -1); + } return 0; } /* read a lump of data at a specified offset, maybe convert */ static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv) { - if (tdb_oob(tdb, off + len) != 0) return -1; + if (tdb_oob(tdb, off + len, 0) != 0) return -1; if (tdb->map_ptr) memcpy(buf, off + (char *)tdb->map_ptr, len); else if (lseek(tdb->fd, off, SEEK_SET) != off - || read(tdb->fd, buf, len) != (ssize_t)len) + || read(tdb->fd, buf, len) != (ssize_t)len) { + TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n", + off, len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_IO, -1); + } if (cv) convert(buf, len); return 0; } @@ -240,7 +286,11 @@ static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len) { char *buf; - if (!(buf = malloc(len))) return TDB_ERRCODE(TDB_ERR_OOM, buf); + if (!(buf = malloc(len))) { + TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n", + len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_OOM, buf); + } if (tdb_read(tdb, offset, buf, len, 0) == -1) { free(buf); return NULL; @@ -263,8 +313,11 @@ static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) { if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) return -1; - if (TDB_BAD_MAGIC(rec)) return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - return tdb_oob(tdb, rec->next); + if (TDB_BAD_MAGIC(rec)) { + TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + return tdb_oob(tdb, rec->next+sizeof(*rec), 0); } static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) { @@ -273,17 +326,15 @@ static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) } /* read a freelist record and check for simple errors */ -static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct*rec) +static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) { if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) return -1; if (rec->magic != TDB_FREE_MAGIC) { -#ifdef TDB_DEBUG - printf("bad magic 0x%08x at offset %d\n", - rec->magic, off); -#endif + TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n", + rec->magic, off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } - if (tdb_oob(tdb, rec->next) != 0) return -1; + if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) return -1; return 0; } @@ -300,10 +351,67 @@ static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset, } #ifdef TDB_DEBUG +static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset) +{ + struct list_struct rec; + tdb_off tailer_ofs, tailer; + + if (tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { + printf("ERROR: failed to read record at %u\n", offset); + return 0; + } + + printf(" rec: offset=%u next=%d rec_len=%d key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", + offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); + + tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off); + if (ofs_read(tdb, tailer_ofs, &tailer) == -1) { + printf("ERROR: failed to read tailer at %u\n", tailer_ofs); + return rec.next; + } + + if (tailer != rec.rec_len + sizeof(rec)) { + printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", tailer, rec.rec_len + sizeof(rec)); + } + return rec.next; +} + +static void tdb_dump_chain(TDB_CONTEXT *tdb, int i) +{ + tdb_off rec_ptr, top; + + top = TDB_HASH_TOP(i); + + tdb_lock(tdb, i, F_WRLCK); + + if (ofs_read(tdb, top, &rec_ptr) == -1) { + tdb_unlock(tdb, i, F_WRLCK); + return; + } + + if (rec_ptr) printf("hash=%d\n", i); + + while (rec_ptr) { + rec_ptr = tdb_dump_record(tdb, rec_ptr); + } + tdb_unlock(tdb, i, F_WRLCK); +} + +void tdb_dump_all(TDB_CONTEXT *tdb) +{ + tdb_off off; + int i; + for (i=0;i<tdb->header.hash_size;i++) { + tdb_dump_chain(tdb, i); + } + printf("freelist:\n"); + tdb_dump_chain(tdb, -1); +} + void tdb_printfreelist(TDB_CONTEXT *tdb) { long total_free = 0; - tdb_off offset, rec_ptr, last_ptr; + tdb_off offset, rec_ptr, last_ptr; struct list_struct rec, lastrec, newrec; tdb_lock(tdb, -1, F_WRLCK); @@ -354,6 +462,7 @@ static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) /* Follow chain (next offset is at start of record) */ last_ptr = i; } + TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } @@ -366,52 +475,76 @@ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; + /* set an initial tailer, so if we fail we don't leave a bogus record */ + update_tailer(tdb, offset, rec); + /* Look right first (I'm an Australian, dammit) */ right = offset + sizeof(*rec) + rec->rec_len; - if (tdb_oob(tdb, right + sizeof(*rec)) == 0) { + if (right + sizeof(*rec) <= tdb->map_size) { struct list_struct r; - if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) - goto fail; + if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { + TDB_LOG((tdb, 0, "tdb_free: right read failed at %u\n", right)); + goto left; + } /* If it's free, expand to include it. */ if (r.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, right, r.next) == -1) - goto fail; + if (remove_from_freelist(tdb, right, r.next) == -1) { + TDB_LOG((tdb, 0, "tdb_free: right free failed at %u\n", right)); + goto left; + } rec->rec_len += sizeof(r) + r.rec_len; } } +left: /* Look left */ - left = offset - 4; + left = offset - sizeof(tdb_off); if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) { struct list_struct l; tdb_off leftsize; /* Read in tailer and jump back to header */ - if (ofs_read(tdb, left, &leftsize) == -1) goto fail; + if (ofs_read(tdb, left, &leftsize) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left)); + goto update; + } left = offset - leftsize; /* Now read in record */ - if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) - goto fail; + if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); + goto update; + } /* If it's free, expand to include it. */ if (l.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, left, l.next) == -1) - goto fail; - offset = left; - rec->rec_len += leftsize; + if (remove_from_freelist(tdb, left, l.next) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left free failed at %u\n", left)); + goto update; + } else { + offset = left; + rec->rec_len += leftsize; + } } } - if (update_tailer(tdb, offset, rec) == -1) goto fail; + +update: + if (update_tailer(tdb, offset, rec) == -1) { + TDB_LOG((tdb, 0, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } /* Now, prepend to free list */ rec->magic = TDB_FREE_MAGIC; - if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1) goto fail; - if (rec_write(tdb, offset, rec) == -1) goto fail; - if (ofs_write(tdb, FREELIST_TOP, &offset) == -1) goto fail; + if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || + rec_write(tdb, offset, rec) == -1 || + ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, 0, "tdb_free record write failed at offset=%d\n", offset)); + goto fail; + } /* And we're done. */ tdb_unlock(tdb, -1, F_WRLCK); @@ -422,37 +555,92 @@ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) return -1; } + +/* expand a file. we prefer to use ftruncate, as that is what posix + says to use for mmap expansion */ +static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition) +{ + char buf[1024]; +#if HAVE_FTRUNCATE_EXTEND + if (ftruncate(tdb->fd, size+addition) != 0) { + TDB_LOG((tdb, 0, "expand_file ftruncate to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } +#else + char b = 0; + if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 || + write(tdb->fd, &b, 1) != 1) { + TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } +#endif + /* now fill the file with something. This ensures that the file isn't sparse, which would be + very bad if we ran out of disk. This must be done with write, not via mmap */ + memset(buf, 0x42, sizeof(buf)); + if (lseek(tdb->fd, size, SEEK_SET) != size) return -1; + while (addition) { + int n = addition>sizeof(buf)?sizeof(buf):addition; + int ret = write(tdb->fd, buf, n); + if (ret != n) { + TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n", + n, strerror(errno))); + return -1; + } + addition -= n; + } + return 0; +} + + /* expand the database at least size bytes by expanding the underlying file and doing the mmap again if necessary */ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) { struct list_struct rec; tdb_off offset; - char b = 0; - if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + TDB_LOG((tdb, 0, "lock failed in tdb_expand\n")); + return 0; + } /* must know about any previous expansions by another process */ - tdb_oob(tdb, tdb->map_size + 1); + tdb_oob(tdb, tdb->map_size + 1, 1); /* always make room for at least 10 more records, and round the database up to a multiple of TDB_PAGE_SIZE */ size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size; - /* expand the file itself */ - if (!(tdb->flags & TDB_INTERNAL)) { - lseek(tdb->fd, tdb->map_size + size - 1, SEEK_SET); - if (write(tdb->fd, &b, 1) != 1) goto fail; - } + if (!(tdb->flags & TDB_INTERNAL)) + tdb_munmap(tdb); + + /* + * We must ensure the file is unmapped before doing this + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ - if (!(tdb->flags & TDB_INTERNAL) && tdb->map_ptr) - tdb->map_ptr = tdb_munmap(tdb->map_ptr, tdb->map_size); + /* expand the file itself */ + if (!(tdb->flags & TDB_INTERNAL)) { + if (expand_file(tdb, tdb->map_size, size) != 0) goto fail; + } tdb->map_size += size; if (tdb->flags & TDB_INTERNAL) tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); + /* + * We must ensure the file is remapped before adding the space + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ + + /* We're ok if the mmap fails as we'll fallback to read/write */ + tdb_mmap(tdb); + /* form a new freelist record */ memset(&rec,'\0',sizeof(rec)); rec.rec_len = size - sizeof(rec); @@ -461,9 +649,6 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) offset = tdb->map_size - size; if (tdb_free(tdb, offset, &rec) == -1) goto fail; - if (!(tdb->flags & TDB_NOMMAP)) - tdb->map_ptr = tdb_mmap(tdb->map_size, 0, tdb->fd); - tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: @@ -739,18 +924,18 @@ int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) /* record lock stops delete underneath */ static int lock_record(TDB_CONTEXT *tdb, tdb_off off) { - return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW) : 0; + return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0; } /* write locks override our own fcntl readlocks, so check it here */ static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) { struct tdb_traverse_lock *i; for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) return -1; - return tdb_brlock(tdb, off, F_WRLCK, F_SETLK); + return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1); } static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) { - return tdb_brlock(tdb, off, F_UNLCK, F_SETLK); + return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0); } /* fcntl locks don't stack: avoid unlocking someone else's */ static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) @@ -760,7 +945,7 @@ static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) if (off == 0) return 0; for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) count++; - return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW) : 0); + return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0); } /* actually delete an entry in the database given the offset */ @@ -859,10 +1044,10 @@ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state) struct tdb_traverse_lock tl = { NULL, 0, 0 }; int ret, count = 0; - /* This was in the initializaton, above, but the IRIX compiler - * did not like it. crh - */ - tl.next = tdb->travlocks.next; + /* This was in the initializaton, above, but the IRIX compiler + * did not like it. crh + */ + tl.next = tdb->travlocks.next; /* fcntl locks don't stack: beware traverse inside traverse */ tdb->travlocks.next = &tl; @@ -895,8 +1080,10 @@ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state) free(key.dptr); } tdb->travlocks.next = tl.next; - if (ret < 0) return -1; - else return count; + if (ret < 0) + return -1; + else + return count; } /* find the first entry in the database and return its key */ @@ -1050,7 +1237,8 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) ret = -1; } out: - free(p); + if (p) + free(p); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); return ret; } @@ -1095,10 +1283,10 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, if ((tdb.fd = open(name, open_flags, mode)) == -1) goto fail; /* ensure there is only one process initialising at once */ - tdb_brlock(&tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW); + tdb_brlock(&tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0); /* we need to zero database if we are the only one with it open */ - if ((locked = (tdb_brlock(&tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK) == 0)) + if ((locked = (tdb_brlock(&tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0)) && (tdb_flags & TDB_CLEAR_IF_FIRST)) { open_flags |= O_CREAT; ftruncate(tdb.fd, 0); @@ -1135,27 +1323,26 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, tdb.inode = st.st_ino; tdb.locked = calloc(tdb.header.hash_size+1, sizeof(tdb.locked[0])); if (!tdb.locked) goto fail; - if (!(tdb.flags & TDB_NOMMAP)) - tdb.map_ptr = tdb_mmap(st.st_size, tdb.read_only, tdb.fd); + tdb_mmap(&tdb); if (locked) { tdb_clear_spinlocks(&tdb); - tdb_brlock(&tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK); + tdb_brlock(&tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0); } /* leave this lock in place to indicate it's in use */ - tdb_brlock(&tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW); + tdb_brlock(&tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0); internal: if (!(ret = malloc(sizeof(tdb)))) goto fail; *ret = tdb; - tdb_brlock(&tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW); + tdb_brlock(&tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0); ret->next = tdbs; tdbs = ret; return ret; fail: - if (tdb.name) free(tdb.name); + if (tdb.name) free(tdb.name); if (tdb.fd != -1) close(tdb.fd); - if (tdb.map_ptr) tdb_munmap(tdb.map_ptr, tdb.map_size); + tdb_munmap(&tdb); return NULL; } @@ -1167,7 +1354,7 @@ int tdb_close(TDB_CONTEXT *tdb) if (tdb->map_ptr) { if (tdb->flags & TDB_INTERNAL) free(tdb->map_ptr); - else tdb_munmap(tdb->map_ptr, tdb->map_size); + else tdb_munmap(tdb); } if (tdb->name) free(tdb->name); if (tdb->fd != -1) { @@ -1276,3 +1463,10 @@ void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) { tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK); } + + +/* register a loging function */ +void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)) +{ + tdb->log_fn = fn; +} diff --git a/source/tdb/tdb.h b/source/tdb/tdb.h index f09c6453b53..cc37825e781 100644 --- a/source/tdb/tdb.h +++ b/source/tdb/tdb.h @@ -94,12 +94,14 @@ typedef struct tdb_context { struct tdb_context *next; /* all tdbs to avoid multiple opens */ dev_t device; /* uniquely identifies this tdb */ ino_t inode; /* uniquely identifies this tdb */ + void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...); /* logging function */ } TDB_CONTEXT; typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); +void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)); enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); const char *tdb_errorstr(TDB_CONTEXT *tdb); TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); diff --git a/source/tdb/tdbtest.c b/source/tdb/tdbtest.c index 9e636eef83a..2cc7e887297 100644 --- a/source/tdb/tdbtest.c +++ b/source/tdb/tdbtest.c @@ -4,6 +4,7 @@ #include <unistd.h> #include <string.h> #include <fcntl.h> +#include <stdarg.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/time.h> @@ -40,6 +41,14 @@ static void fatal(char *why) exit(1); } +static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); +} static void compare_db(void) { @@ -230,6 +239,7 @@ int main(int argc, char *argv[]) fatal("db open failed"); } + tdb_logging_function(db, tdb_log); #if 1 srand(seed); diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c index 27454f73dea..8c09c76df55 100644 --- a/source/tdb/tdbtool.c +++ b/source/tdb/tdbtool.c @@ -363,6 +363,8 @@ int main(int argc, char *argv[]) } else if (strcmp(tok,"dump") == 0) { bIterate = 0; tdb_traverse(tdb, print_rec, NULL); + } else if (strcmp(tok,"list") == 0) { + tdb_dump_all(tdb); } else if (strcmp(tok,"info") == 0) { info_tdb(); } else if (strcmp(tok, "free") == 0) { diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c index 90dcc38aba1..1a3b715402d 100644 --- a/source/tdb/tdbtorture.c +++ b/source/tdb/tdbtorture.c @@ -4,9 +4,11 @@ #include <unistd.h> #include <string.h> #include <fcntl.h> +#include <stdarg.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/time.h> +#include <sys/wait.h> #include "tdb.h" /* this tests tdb by doing lots of ops from several simultaneous @@ -15,13 +17,32 @@ -#define DELETE_PROB 7 -#define STORE_PROB 5 +#define DELETE_PROB 10 +#define STORE_PROB 3 +#define TRAVERSE_PROB 8 +#define CULL_PROB 60 #define KEYLEN 3 #define DATALEN 100 static TDB_CONTEXT *db; +static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); +#if 0 + { + char *ptr; + asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); + system(ptr); + free(ptr); + } +#endif +} + static void fatal(char *why) { perror(why); @@ -41,6 +62,15 @@ static char *randbuf(int len) return buf; } +static int cull_traverse(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, + void *state) +{ + if (random() % CULL_PROB == 0) { + tdb_delete(db, key); + } + return 0; +} + static void addrec_db(void) { int klen, dlen; @@ -59,12 +89,14 @@ static void addrec_db(void) data.dptr = d; data.dsize = dlen+1; - if (rand() % DELETE_PROB == 0) { + if (random() % DELETE_PROB == 0) { tdb_delete(db, key); - } else if (rand() % STORE_PROB == 0) { + } else if (random() % STORE_PROB == 0) { if (tdb_store(db, key, data, TDB_REPLACE) != 0) { fatal("tdb_store failed"); } + } else if (random() % TRAVERSE_PROB == 0) { + tdb_traverse(db, cull_traverse, NULL); } else { data = tdb_fetch(db, key); if (data.dptr) free(data.dptr); @@ -82,20 +114,23 @@ static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, } #ifndef NPROC -#define NPROC 8 +#define NPROC 6 #endif #ifndef NLOOPS -#define NLOOPS 50000 +#define NLOOPS 200000 #endif int main(int argc, char *argv[]) { int i, seed=0; int loops = NLOOPS; + pid_t pids[NPROC]; + + pids[0] = getpid(); for (i=0;i<NPROC-1;i++) { - if (fork() == 0) break; + if ((pids[i+1]=fork()) == 0) break; } db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, @@ -103,15 +138,34 @@ int main(int argc, char *argv[]) if (!db) { fatal("db open failed"); } + tdb_logging_function(db, tdb_log); srand(seed + getpid()); + srandom(seed + getpid() + time(NULL)); for (i=0;i<loops;i++) addrec_db(); - printf("traversed %d records\n", tdb_traverse(db, NULL, NULL)); - printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL)); - printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL)); + tdb_traverse(db, NULL, NULL); + tdb_traverse(db, traverse_fn, NULL); + tdb_traverse(db, traverse_fn, NULL); tdb_close(db); + if (getpid() == pids[0]) { + for (i=0;i<NPROC-1;i++) { + int status; + if (waitpid(pids[i+1], &status, 0) != pids[i+1]) { + printf("failed to wait for %d\n", + (int)pids[i+1]); + exit(1); + } + if (WEXITSTATUS(status) != 0) { + printf("child %d exited with status %d\n", + (int)pids[i+1], WEXITSTATUS(status)); + exit(1); + } + } + printf("OK\n"); + } + return 0; } diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c index 6b4fe2d0245..0a2f1f84d45 100644 --- a/source/tdb/tdbutil.c +++ b/source/tdb/tdbutil.c @@ -46,9 +46,6 @@ void tdb_unlock_bystring(TDB_CONTEXT *tdb, char *keyval) tdb_chainunlock(tdb, key); } -/* lock a chain by string key */ - - /* fetch a value by a arbitrary blob key, return -1 if not found */ int tdb_fetch_int_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len) { @@ -107,6 +104,7 @@ int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len) /* Fetch a buffer using a null terminated string key. Don't forget to call free() on the result dptr. */ + TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr) { TDB_DATA key; @@ -117,6 +115,37 @@ TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr) return tdb_fetch(tdb, key); } +/* Atomic integer change. Returns old value. To create, set initial value in *oldval. */ + +int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val) +{ + int val; + int ret = -1; + + if (tdb_lock_bystring(tdb, keystr) == -1) + return -1; + + if ((val = tdb_fetch_int(tdb, keystr)) == -1) { + if (tdb_error(tdb) != TDB_ERR_NOEXIST) + goto err_out; + + val = *oldval; + + } else { + *oldval = val; + val += change_val; + } + + if (tdb_store_int(tdb, keystr, val) == -1) + goto err_out; + + ret = 0; + + err_out: + + tdb_unlock_bystring(tdb, keystr); + return ret; +} /* useful pair of routines for packing/unpacking data consisting of integers and strings */ @@ -208,6 +237,7 @@ size_t tdb_pack(char *buf, int bufsize, char *fmt, ...) /* useful pair of routines for packing/unpacking data consisting of integers and strings */ + int tdb_unpack(char *buf, int bufsize, char *fmt, ...) { va_list ap; @@ -262,7 +292,10 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...) len = 4; if (bufsize < len) goto no_space; *i = IVAL(buf, 0); - if (! *i) break; + if (! *i) { + *b = NULL; + break; + } len += *i; if (bufsize < len) goto no_space; *b = (char *)malloc(*i); @@ -291,3 +324,37 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...) no_space: return -1; } + +/**************************************************************************** +log tdb messages via DEBUG() +****************************************************************************/ +static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) +{ + va_list ap; + char *ptr = NULL; + + va_start(ap, format); + vasprintf(&ptr, format, ap); + va_end(ap); + + if (!ptr || !*ptr) return; + + DEBUG(level, ("tdb(%s): %s", tdb->name, ptr)); + free(ptr); +} + + + +/* like tdb_open() but also setup a logging function that redirects to + the samba DEBUG() system */ +TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + TDB_CONTEXT *tdb = tdb_open(name, hash_size, tdb_flags, + open_flags, mode); + if (!tdb) return NULL; + + tdb_logging_function(tdb, tdb_log); + + return tdb; +} diff --git a/source/tests/fcntl_lock.c b/source/tests/fcntl_lock.c index 32aecb87439..3dc12a38973 100644 --- a/source/tests/fcntl_lock.c +++ b/source/tests/fcntl_lock.c @@ -16,6 +16,10 @@ #include <sys/fcntl.h> #endif +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + #include <errno.h> static int sys_waitpid(pid_t pid,int *status,int options) @@ -39,12 +43,22 @@ int main(int argc, char *argv[]) struct flock lock; int fd, ret, status=1; pid_t pid; + char *testdir = NULL; + + testdir = getenv("TESTDIR"); + if (testdir) chdir(testdir); + + alarm(10); if (!(pid=fork())) { sleep(2); fd = open(DATA, O_RDONLY); - if (fd == -1) exit(1); + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; @@ -59,13 +73,21 @@ int main(int argc, char *argv[]) if ((ret == -1) || (lock.l_type == F_UNLCK)) { + fprintf(stderr,"ERROR: lock test failed (ret=%d errno=%d)\n", ret, (int)errno); exit(1); } else { exit(0); } } - fd = open(DATA, O_RDWR|O_CREAT|O_TRUNC, 0600); + unlink(DATA); + fd = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600); + + if (fd == -1) { + fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", + DATA, (int)errno); + exit(1); + } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; @@ -90,5 +112,10 @@ int main(int argc, char *argv[]) status = (status == 0) ? 0 : 1; #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */ + if (status) { + fprintf(stderr,"ERROR: lock test failed with status=%d\n", + status); + } + exit(status); } diff --git a/source/utils/make_unicodemap.c b/source/utils/make_unicodemap.c index ff9bb19b6fe..3584facbf62 100644 --- a/source/utils/make_unicodemap.c +++ b/source/utils/make_unicodemap.c @@ -149,7 +149,7 @@ static int do_compile(const char *codepage, const char *input_file, const char * SMB_STRUCT_STAT st; /* Get the size of the input file. Read the entire thing into memory. */ - if(sys_stat((char *)input_file, &st)!= 0) { + if(sys_stat(input_file, &st)!= 0) { fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n", prog_name, input_file, strerror(errno)); exit(1); diff --git a/source/utils/masktest.c b/source/utils/masktest.c index 3fc7431519a..a654b5bfd11 100644 --- a/source/utils/masktest.c +++ b/source/utils/masktest.c @@ -27,34 +27,130 @@ extern int DEBUGLEVEL; static fstring password; static fstring username; static int got_pass; - +static int max_protocol = PROTOCOL_NT1; static BOOL showall = False; static BOOL old_list = False; static char *maskchars = "<>\"?*abc."; static char *filechars = "abcdefghijklm."; +static int verbose; +static int die_on_error; -static BOOL reg_match_one(char *pattern, char *file) +/* a test fn for LANMAN mask support */ +int ms_fnmatch_lanman_core(char *pattern, char *string) { - if (strcmp(file,"..") == 0) file = "."; - if (strcmp(pattern,".") == 0) return False; + char *p = pattern, *n = string; + char c; + + if (strcmp(p,"?")==0 && strcmp(n,".")==0) goto match; + + while ((c = *p++)) { + switch (c) { + case '.': + /* if (! *n && ! *p) goto match; */ + if (*n != '.') goto nomatch; + n++; + break; + + case '?': + if ((*n == '.' && n[1] != '.') || ! *n) goto next; + n++; + break; + + case '>': + if (n[0] == '.') { + if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + goto nomatch; + } + if (! *n) goto next; + n++; + break; + + case '*': + if (! *p) goto match; + for (; *n; n++) { + if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + } + break; + case '<': + for (; *n; n++) { + if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (*n == '.' && !strchr(n+1,'.')) { + n++; + break; + } + } + break; + + case '"': + if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (*n != '.') goto nomatch; + n++; + break; + + default: + if (c != *n) goto nomatch; + n++; + } + } + + if (! *n) goto match; + + nomatch: + if (verbose) printf("NOMATCH pattern=[%s] string=[%s]\n", pattern, string); + return -1; + +next: + if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + goto nomatch; + + match: + if (verbose) printf("MATCH pattern=[%s] string=[%s]\n", pattern, string); + return 0; +} + +int ms_fnmatch_lanman(char *pattern, char *string) +{ + if (!strpbrk(pattern, "?*<>\"")) { + if (strcmp(string,"..") == 0) string = "."; + return strcmp(pattern, string); + } + + if (strcmp(string,"..") == 0 || strcmp(string,".") == 0) { + return ms_fnmatch_lanman_core(pattern, "..") && + ms_fnmatch_lanman_core(pattern, "."); + } + + return ms_fnmatch_lanman_core(pattern, string); +} + +static BOOL reg_match_one(char *pattern, char *file) +{ /* oh what a weird world this is */ if (old_list && strcmp(pattern, "*.*") == 0) return True; + if (strcmp(pattern,".") == 0) return False; + + if (max_protocol <= PROTOCOL_LANMAN2) { + return ms_fnmatch_lanman(pattern, file)==0; + } + + if (strcmp(file,"..") == 0) file = "."; + return ms_fnmatch(pattern, file)==0; } -static char *reg_test(char *pattern, char *file, char *short_name) +static char *reg_test(char *pattern, char *long_name, char *short_name) { static fstring ret; fstrcpy(ret, "---"); pattern = 1+strrchr(pattern,'\\'); - file = 1+strrchr(file,'\\'); if (reg_match_one(pattern, ".")) ret[0] = '+'; if (reg_match_one(pattern, "..")) ret[1] = '+'; - if (reg_match_one(pattern, file) || + if (reg_match_one(pattern, long_name) || (*short_name && reg_match_one(pattern, short_name))) ret[2] = '+'; return ret; } @@ -95,6 +191,8 @@ struct cli_state *connect_one(char *share) return NULL; } + c->protocol = max_protocol; + if (!cli_session_request(c, &calling, &called)) { DEBUG(0,("session request to %s failed\n", called.name)); cli_shutdown(c); @@ -157,7 +255,7 @@ struct cli_state *connect_one(char *share) static char *resultp; static file_info *finfo; -void listfn(file_info *f, const char *s) +void listfn(file_info *f, const char *s, void *state) { if (strcmp(f->name,".") == 0) { resultp[0] = '+'; @@ -169,14 +267,32 @@ void listfn(file_info *f, const char *s) finfo = f; } -static void get_short_name(struct cli_state *cli, - char *name, fstring short_name) +static void get_real_name(struct cli_state *cli, + pstring long_name, fstring short_name) { - cli_list(cli, name, aHIDDEN | aDIR, listfn); + /* nasty hack to force level 260 listings - tridge */ + cli->capabilities |= CAP_NT_SMBS; + if (max_protocol <= PROTOCOL_LANMAN1) { + cli_list_new(cli, "\\masktest\\*.*", aHIDDEN | aDIR, listfn, NULL); + } else { + cli_list_new(cli, "\\masktest\\*", aHIDDEN | aDIR, listfn, NULL); + } if (finfo) { fstrcpy(short_name, finfo->short_name); strlower(short_name); + pstrcpy(long_name, finfo->name); + strlower(long_name); + } + + if (*short_name == 0) { + fstrcpy(short_name, long_name); } + +#if 0 + if (!strchr(short_name,'.')) { + fstrcat(short_name,"."); + } +#endif } static void testpair(struct cli_state *cli, char *mask, char *file) @@ -186,6 +302,7 @@ static void testpair(struct cli_state *cli, char *mask, char *file) char *res2; static int count; fstring short_name; + pstring long_name; count++; @@ -201,20 +318,17 @@ static void testpair(struct cli_state *cli, char *mask, char *file) resultp = res1; fstrcpy(short_name, ""); finfo = NULL; - if (old_list) { - cli_list_old(cli, mask, aHIDDEN | aDIR, listfn); - } else { - get_short_name(cli, file, short_name); - finfo = NULL; - fstrcpy(res1, "---"); - cli_list(cli, mask, aHIDDEN | aDIR, listfn); - } + get_real_name(cli, long_name, short_name); + finfo = NULL; + fstrcpy(res1, "---"); + cli_list(cli, mask, aHIDDEN | aDIR, listfn, NULL); - res2 = reg_test(mask, file, short_name); + res2 = reg_test(mask, long_name, short_name); if (showall || strcmp(res1, res2)) { - DEBUG(0,("%s %s %d mask=[%s] file=[%s] mfile=[%s]\n", - res1, res2, count, mask, file, short_name)); + DEBUG(0,("%s %s %d mask=[%s] file=[%s] rfile=[%s/%s]\n", + res1, res2, count, mask, file, long_name, short_name)); + if (die_on_error) exit(1); } cli_unlink(cli, file); @@ -267,6 +381,8 @@ static void test_mask(int argc, char *argv[], strcmp(file+l,"..") == 0 || strcmp(mask+l,"..") == 0) continue; + if (strspn(file+l, ".") == strlen(file+l)) continue; + testpair(cli, mask, file); } @@ -341,8 +457,17 @@ static void usage(void) seed = time(NULL); - while ((opt = getopt(argc, argv, "U:s:hm:f:aoW:")) != EOF) { + while ((opt = getopt(argc, argv, "U:s:hm:f:aoW:M:vE")) != EOF) { switch (opt) { + case 'E': + die_on_error = 1; + break; + case 'v': + verbose++; + break; + case 'M': + max_protocol = interpret_protocol(optarg, max_protocol); + break; case 'U': pstrcpy(username,optarg); p = strchr(username,'%'); diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c index 4e85f6ac456..0f978a6cf3f 100644 --- a/source/utils/nmblookup.c +++ b/source/utils/nmblookup.c @@ -118,7 +118,7 @@ static void do_node_status(int fd, char *name, int type, struct in_addr ip) for (i=0;i<count;i++) { fstrcpy(cleanname, status[i].name); for (j=0;cleanname[j];j++) { - if (!isprint(cleanname[j])) cleanname[j] = '.'; + if (!isprint((int)cleanname[j])) cleanname[j] = '.'; } printf("\t%-15s <%02x> - %s\n", cleanname,status[i].type, diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c index 4803da9f33d..028eb481a65 100644 --- a/source/utils/smbcacls.c +++ b/source/utils/smbcacls.c @@ -92,7 +92,7 @@ static BOOL cacls_open_policy_hnd(void) /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 so we might as well do it too. */ - if (cli_lsa_open_policy(&lsa_cli, True, + if (cli_lsa_open_policy(&lsa_cli, lsa_cli.mem_ctx, True, GENERIC_EXECUTE_ACCESS, &pol) != NT_STATUS_NOPROBLEMO) { return False; @@ -118,7 +118,7 @@ static void SidToString(fstring str, DOM_SID *sid) /* Ask LSA to convert the sid to a name */ if (!cacls_open_policy_hnd() || - cli_lsa_lookup_sids(&lsa_cli, &pol, 1, sid, &names, &types, + cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, sid, &names, &types, &num_names) != NT_STATUS_NOPROBLEMO || !names || !names[0]) { return; @@ -127,10 +127,6 @@ static void SidToString(fstring str, DOM_SID *sid) /* Converted OK */ fstrcpy(str, names[0]); - - safe_free(names[0]); - safe_free(names); - safe_free(types); } /* convert a string to a SID, either numeric or username/group */ @@ -146,7 +142,7 @@ static BOOL StringToSid(DOM_SID *sid, char *str) } if (!cacls_open_policy_hnd() || - cli_lsa_lookup_names(&lsa_cli, &pol, 1, &str, &sids, &types, + cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, &str, &sids, &types, &num_sids) != NT_STATUS_NOPROBLEMO) { result = False; goto done; @@ -154,9 +150,6 @@ static BOOL StringToSid(DOM_SID *sid, char *str) sid_copy(sid, &sids[0]); - safe_free(sids); - safe_free(types); - done: return result; @@ -347,7 +340,7 @@ static SEC_DESC *sec_desc_parse(char *str) char *p = str; fstring tok; SEC_DESC *ret; - unsigned sd_size; + size_t sd_size; DOM_SID *grp_sid=NULL, *owner_sid=NULL; SEC_ACL *dacl=NULL; int revision=1; @@ -458,7 +451,7 @@ static int cacl_dump(struct cli_state *cli, char *filename) return EXIT_FAILED; } - sd = cli_query_secdesc(cli, fnum); + sd = cli_query_secdesc(cli, fnum, ctx); if (!sd) { printf("ERROR: secdesc query failed: %s\n", cli_errstr(cli)); @@ -495,7 +488,7 @@ static int owner_set(struct cli_state *cli, enum chown_mode change_mode, if (!StringToSid(&sid, new_username)) return EXIT_PARSE_ERROR; - old = cli_query_secdesc(cli, fnum); + old = cli_query_secdesc(cli, fnum, ctx); cli_close(cli, fnum); @@ -589,7 +582,7 @@ static int cacl_set(struct cli_state *cli, char *filename, return EXIT_FAILED; } - old = cli_query_secdesc(cli, fnum); + old = cli_query_secdesc(cli, fnum, ctx); if (!old) { printf("calc_set: Failed to query old descriptor\n"); @@ -817,7 +810,7 @@ You can string acls together with spaces, commas or newlines\n\ char *p; static pstring servicesf = CONFIGFILE; struct cli_state *cli=NULL; - enum acl_mode mode; + enum acl_mode mode = SMB_ACL_SET; char *the_acl = NULL; enum chown_mode change_mode = REQUEST_NONE; int result; diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c index c5462ea1fb7..631bcf9bb90 100644 --- a/source/utils/smbcontrol.c +++ b/source/utils/smbcontrol.c @@ -32,6 +32,7 @@ static struct { {"profilelevel", MSG_REQ_PROFILELEVEL}, {"debuglevel", MSG_REQ_DEBUGLEVEL}, {"printer-notify", MSG_PRINTER_NOTIFY}, + {"close-share", MSG_SMB_FORCE_TDIS}, {NULL, -1} }; @@ -69,7 +70,7 @@ a useful function for testing the message system void pong_function(int msg_type, pid_t src, void *buf, size_t len) { pong_count++; - printf("PONG from PID %d\n",src); + printf("PONG from PID %u\n",(unsigned int)src); } /**************************************************************************** @@ -82,7 +83,7 @@ void debuglevel_function(int msg_type, pid_t src, void *buf, size_t len) memcpy(debuglevel_class, buf, len); - printf("Current debug level of PID %d is %d ",src, debuglevel_class[0]); + printf("Current debug level of PID %u is %d ",(unsigned int)src, debuglevel_class[0]); for (i=1;i<DBGC_LAST;i++) if (debuglevel_class[i]) printf("%s:%d ", debug_classname_from_index(i), debuglevel_class[i]); @@ -112,9 +113,9 @@ void profilelevel_function(int msg_type, pid_t src, void *buf, size_t len) s = "count and time"; break; } - printf("Profiling %s on PID %d\n",s,src); + printf("Profiling %s on PID %u\n",s,(unsigned int)src); } else { - printf("Profiling not available on PID %d\n",src); + printf("Profiling not available on PID %u\n",(unsigned int)src); } got_level = True; } @@ -127,7 +128,7 @@ static BOOL send_message(char *dest, int msg_type, void *buf, int len, BOOL dupl pid_t pid; TDB_CONTEXT *the_tdb; - the_tdb = tdb_open(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0); + the_tdb = tdb_open_log(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0); if (!the_tdb) { fprintf(stderr,"Failed to open connections database in send_message.\n"); return False; @@ -171,7 +172,7 @@ static int parse_type(char *mtype) /**************************************************************************** do command ****************************************************************************/ -static BOOL do_command(char *dest, char *msg_name, char *params[]) +static BOOL do_command(char *dest, char *msg_name, char **params) { int i, n, v; int mtype; @@ -186,7 +187,7 @@ static BOOL do_command(char *dest, char *msg_name, char *params[]) switch (mtype) { case MSG_DEBUG: - if (!params[0]) { + if (!params || !params[0]) { fprintf(stderr,"MSG_DEBUG needs a parameter\n"); return(False); } @@ -200,7 +201,7 @@ static BOOL do_command(char *dest, char *msg_name, char *params[]) break; case MSG_PROFILE: - if (!params[0]) { + if (!params || !params[0]) { fprintf(stderr,"MSG_PROFILE needs a parameter\n"); return(False); } @@ -271,7 +272,7 @@ static BOOL do_command(char *dest, char *msg_name, char *params[]) fprintf(stderr,"printer-notify can only be sent to smbd\n"); return(False); } - if (!params[0]) { + if (!params || !params[0]) { fprintf(stderr, "printer-notify needs a printer name\n"); return (False); } @@ -279,12 +280,25 @@ static BOOL do_command(char *dest, char *msg_name, char *params[]) strlen(params[0]) + 1, False); break; + 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; + case MSG_PING: if (!pong_registered) { message_register(MSG_PONG, pong_function); pong_registered = True; } - if (!params[0]) { + if (!params || !params[0]) { fprintf(stderr,"MSG_PING needs a parameter\n"); return(False); } diff --git a/source/utils/smbfilter.c b/source/utils/smbfilter.c index 5d11c74d149..db83873e694 100644 --- a/source/utils/smbfilter.c +++ b/source/utils/smbfilter.c @@ -26,11 +26,11 @@ #define SECURITY_SET 0 /* this forces non-unicode */ -#define CAPABILITY_MASK CAP_UNICODE +#define CAPABILITY_MASK (CAP_NT_SMBS | CAP_RPC_REMOTE_APIS) #define CAPABILITY_SET 0 /* and non-unicode for the client too */ -#define CLI_CAPABILITY_MASK CAP_UNICODE +#define CLI_CAPABILITY_MASK 0 #define CLI_CAPABILITY_SET 0 static char *netbiosname; @@ -179,7 +179,7 @@ static void start_filter(char *desthost) fd_set fds; int num; struct sockaddr addr; - int in_addrlen = sizeof(addr); + socklen_t in_addrlen = sizeof(addr); FD_ZERO(&fds); FD_SET(s, &fds); diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c index 524cd5b8ad0..839ce6f046e 100644 --- a/source/utils/smbpasswd.c +++ b/source/utils/smbpasswd.c @@ -29,6 +29,9 @@ extern int DEBUGLEVEL; extern char *optarg; extern int optind; +/* forced running in root-mode */ +static BOOL local_mode; + /********************************************************* a strdup with exit **********************************************************/ @@ -59,7 +62,8 @@ static void usage(void) printf(" -U USER remote username\n"); printf(" -r MACHINE remote machine\n"); - if (getuid() == 0) { + if (getuid() == 0 || local_mode) { + printf(" -L local mode (must be first option)\n"); printf(" -R ORDER name resolve order\n"); printf(" -j DOMAIN join domain name\n"); printf(" -a add user\n"); @@ -261,8 +265,11 @@ static int process_root(int argc, char *argv[]) char *old_passwd = NULL; char *remote_machine = NULL; - while ((ch = getopt(argc, argv, "ax:d:e:mnj:r:sR:D:U:")) != EOF) { + while ((ch = getopt(argc, argv, "ax:d:e:mnj:r:sR:D:U:L")) != EOF) { switch(ch) { + case 'L': + local_mode = True; + break; case 'a': local_flags |= LOCAL_ADD_USER; break; @@ -319,10 +326,13 @@ static int process_root(int argc, char *argv[]) argv += optind; /* + * Ensure both add/delete user are not set * Ensure add/delete user and either remote machine or join domain are * not both set. */ - if((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && ((remote_machine != NULL) || joining_domain)) { + if(((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER)) || + ((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && + ((remote_machine != NULL) || joining_domain))) { usage(); } @@ -595,7 +605,14 @@ int main(int argc, char **argv) exit(1); } - if (getuid() == 0) { + /* pre-check for local mode option as first option. We can't + do this via normal getopt as getopt can't be called + twice. */ + if (argc > 1 && strcmp(argv[1], "-L") == 0) { + local_mode = True; + } + + if (local_mode || getuid() == 0) { return process_root(argc, argv); } diff --git a/source/utils/smbw_sample.c b/source/utils/smbw_sample.c index 999dcaef477..db92af95108 100644 --- a/source/utils/smbw_sample.c +++ b/source/utils/smbw_sample.c @@ -34,6 +34,8 @@ int main(int argc, char *argv[]) char *path; charset_initialise(); + lp_load(CONFIGFILE,1,0,0); + codepage_initialise(lp_client_code_page()); smbw_setup_shared(); while ((opt = getopt(argc, argv, "W:U:R:d:P:l:hL:")) != EOF) { diff --git a/source/utils/status.c b/source/utils/status.c index 06abd09d929..4d7792e515a 100644 --- a/source/utils/status.c +++ b/source/utils/status.c @@ -186,9 +186,13 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st struct session_record *ptr; struct connections_data crec; + if (dbuf.dsize != sizeof(crec)) + return 0; + memcpy(&crec, dbuf.dptr, sizeof(crec)); - if (crec.cnum == -1) return 0; + if (crec.cnum == -1) + return 0; if (!process_exists(crec.pid) || !Ucrit_checkUsername(uidtoname(crec.uid))) { return 0; @@ -306,7 +310,7 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st return profile_dump(); } - tdb = tdb_open(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0); + tdb = tdb_open_log(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0); if (!tdb) { printf("connections.tdb not initialised\n"); if (!lp_status(-1)) diff --git a/source/utils/testparm.c b/source/utils/testparm.c index 20f36fcffe4..ae4a12a8825 100644 --- a/source/utils/testparm.c +++ b/source/utils/testparm.c @@ -93,29 +93,37 @@ to a valid password server.\n", sec_setting ); if(lp_security() == SEC_USER && lp_unix_password_sync()) { /* - * Check that we have a valid lp_passwd_program(). + * Check that we have a valid lp_passwd_program() if not using pam. */ - if(lp_passwd_program() == NULL) { - printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \ +#ifdef WITH_PAM + if (!lp_pam_password_change()) { +#endif + + if(lp_passwd_program() == NULL) { + printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \ parameter.\n" ); - ret = 1; - } else { - pstring passwd_prog; - pstring truncated_prog; - char *p; - - pstrcpy( passwd_prog, lp_passwd_program()); - p = passwd_prog; - *truncated_prog = '\0'; - next_token(&p, truncated_prog, NULL, sizeof(pstring)); - - if(access(truncated_prog, F_OK) == -1) { - printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \ -cannot be executed (error was %s).\n", truncated_prog, strerror(errno) ); ret = 1; + } else { + pstring passwd_prog; + pstring truncated_prog; + char *p; + + pstrcpy( passwd_prog, lp_passwd_program()); + p = passwd_prog; + *truncated_prog = '\0'; + next_token(&p, truncated_prog, NULL, sizeof(pstring)); + + if(access(truncated_prog, F_OK) == -1) { + printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \ +cannot be executed (error was %s).\n", truncated_prog, strerror(errno) ); + ret = 1; + } } + +#ifdef WITH_PAM } +#endif if(lp_passwd_chat() == NULL) { printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \ diff --git a/source/utils/torture.c b/source/utils/torture.c index aaeb55eff7c..7fef427f364 100644 --- a/source/utils/torture.c +++ b/source/utils/torture.c @@ -22,8 +22,6 @@ #define NO_SYSLOG #include "includes.h" -#include <sys/ipc.h> -#include <sys/shm.h> static fstring host, workgroup, share, password, username, myname; static int max_protocol = PROTOCOL_NT1; @@ -35,7 +33,7 @@ static fstring randomfname; static BOOL use_oplocks; static BOOL use_level_II_oplocks; -static double create_procs(void (*fn)(int)); +static double create_procs(BOOL (*fn)(int), BOOL *result); static struct timeval tp1,tp2; @@ -155,13 +153,17 @@ static BOOL open_connection(struct cli_state *c) } -static void close_connection(struct cli_state *c) +static BOOL close_connection(struct cli_state *c) { + BOOL ret = True; if (!cli_tdis(c)) { printf("tdis failed (%s)\n", cli_errstr(c)); + ret = False; } - cli_shutdown(c); + cli_shutdown(c); + + return ret; } @@ -202,6 +204,7 @@ static BOOL rw_torture(struct cli_state *c) pid_t pid2, pid = getpid(); int i, j; char buf[1024]; + BOOL correct = True; fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE); @@ -227,11 +230,13 @@ static BOOL rw_torture(struct cli_state *c) fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL); if (fnum == -1) { printf("open failed (%s)\n", cli_errstr(c)); + correct = False; break; } if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) { printf("write failed (%s)\n", cli_errstr(c)); + correct = False; } for (j=0;j<50;j++) { @@ -239,6 +244,7 @@ static BOOL rw_torture(struct cli_state *c) sizeof(pid)+(j*sizeof(buf)), sizeof(buf)) != sizeof(buf)) { printf("write failed (%s)\n", cli_errstr(c)); + correct = False; } } @@ -246,22 +252,27 @@ static BOOL rw_torture(struct cli_state *c) if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) { printf("read failed (%s)\n", cli_errstr(c)); + correct = False; } if (pid2 != pid) { printf("data corruption!\n"); + correct = False; } if (!cli_close(c, fnum)) { printf("close failed (%s)\n", cli_errstr(c)); + correct = False; } if (!cli_unlink(c, fname)) { printf("unlink failed (%s)\n", cli_errstr(c)); + correct = False; } if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) { printf("unlock failed (%s)\n", cli_errstr(c)); + correct = False; } } @@ -270,20 +281,25 @@ static BOOL rw_torture(struct cli_state *c) printf("%d\n", i); - return True; + return correct; } -static void run_torture(int dummy) +static BOOL run_torture(int dummy) { struct cli_state cli; + BOOL ret; cli = current_cli; cli_sockopt(&cli, sockops); - rw_torture(&cli); + ret = rw_torture(&cli); - close_connection(&cli); + if (!close_connection(&cli)) { + ret = False; + } + + return ret; } static BOOL rw_torture3(struct cli_state *c, char *lockfname) @@ -295,6 +311,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname) unsigned count; unsigned countprev = 0; unsigned sent = 0; + BOOL correct = True; srandom(1); for (i = 0; i < sizeof(buf); i += sizeof(uint32)) @@ -347,6 +364,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname) if (cli_write(c, fnum, 0, buf+count, count, sent) != sent) { printf("write failed (%s)\n", cli_errstr(c)); + correct = False; } } else @@ -358,6 +376,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname) printf("read failed offset:%d size:%d (%s)\n", count, sizeof(buf)-count, cli_errstr(c)); + correct = False; sent = 0; } if (sent > 0) @@ -367,6 +386,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname) printf("read/write compare failed\n"); printf("offset: %d req %d recvd %d\n", count, sizeof(buf)-count, sent); + correct = False; break; } } @@ -376,9 +396,10 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname) if (!cli_close(c, fnum)) { printf("close failed (%s)\n", cli_errstr(c)); + correct = False; } - return True; + return correct; } static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2) @@ -389,9 +410,11 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2) int i; char buf[131072]; char buf_rd[131072]; + BOOL correct = True; + ssize_t bytes_read; if (!cli_unlink(c1, lockfname)) { - printf("unlink failed (%s)\n", cli_errstr(c1)); + printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1)); } fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, @@ -412,7 +435,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2) for (i=0;i<numops;i++) { - unsigned buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1; + size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1; if (i % 10 == 0) { printf("%d\r", i); fflush(stdout); } @@ -421,56 +444,70 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2) if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) { printf("write failed (%s)\n", cli_errstr(c1)); + correct = False; } - if (cli_read(c2, fnum2, buf_rd, 0, buf_size) != buf_size) { + if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) { printf("read failed (%s)\n", cli_errstr(c2)); + printf("read %d, expected %d\n", bytes_read, buf_size); + correct = False; } if (memcmp(buf_rd, buf, buf_size) != 0) { printf("read/write compare failed\n"); + correct = False; } } if (!cli_close(c2, fnum2)) { printf("close failed (%s)\n", cli_errstr(c2)); + correct = False; } if (!cli_close(c1, fnum1)) { printf("close failed (%s)\n", cli_errstr(c1)); + correct = False; } if (!cli_unlink(c1, lockfname)) { printf("unlink failed (%s)\n", cli_errstr(c1)); + correct = False; } - return True; + return correct; } -static void run_readwritetest(int dummy) +static BOOL run_readwritetest(int dummy) { static struct cli_state cli1, cli2; - BOOL test; + BOOL test1, test2; if (!open_connection(&cli1) || !open_connection(&cli2)) { - return; + return False; } cli_sockopt(&cli1, sockops); cli_sockopt(&cli2, sockops); printf("starting readwritetest\n"); - test = rw_torture2(&cli1, &cli2); - printf("Passed readwritetest v1: %s\n", BOOLSTR(test)); + test1 = rw_torture2(&cli1, &cli2); + printf("Passed readwritetest v1: %s\n", BOOLSTR(test1)); - test = rw_torture2(&cli1, &cli1); - printf("Passed readwritetest v2: %s\n", BOOLSTR(test)); + test2 = rw_torture2(&cli1, &cli1); + printf("Passed readwritetest v2: %s\n", BOOLSTR(test2)); - close_connection(&cli1); - close_connection(&cli2); + if (!close_connection(&cli1)) { + test1 = False; + } + + if (!close_connection(&cli2)) { + test2 = False; + } + + return (test1 && test2); } -static void run_readwritemulti(int dummy) +static BOOL run_readwritemulti(int dummy) { static struct cli_state cli; BOOL test; @@ -482,13 +519,87 @@ static void run_readwritemulti(int dummy) printf("run_readwritemulti: fname %s\n", randomfname); test = rw_torture3(&cli, randomfname); - close_connection(&cli); + if (!close_connection(&cli)) { + test = False; + } + + return test; } +static BOOL run_readwritelarge(int dummy) +{ + static struct cli_state cli1; + int fnum1; + char *lockfname = "\\large.dat"; + size_t fsize; + char buf[0x10000]; + BOOL correct = True; + + if (!open_connection(&cli1)) { + return False; + } + cli_sockopt(&cli1, sockops); + memset(buf,'\0',sizeof(buf)); + + cli1.max_xmit = 0x11000; + + printf("starting readwritelarge\n"); + + cli_unlink(&cli1, lockfname); + + fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE); + if (fnum1 == -1) { + printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1)); + return False; + } + + cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)); + + if (!cli_close(&cli1, fnum1)) { + printf("close failed (%s)\n", cli_errstr(&cli1)); + correct = False; + } + + if (!cli_qpathinfo(&cli1, lockfname, NULL, NULL, NULL, &fsize, NULL)) { + printf("qpathinfo failed (%s)\n", cli_errstr(&cli1)); + correct = False; + } + + if (fsize == sizeof(buf)) + printf("readwritelarge test 1 succeeded (size = %x)\n", fsize); + else { + printf("readwritelarge test 1 failed (size = %x)\n", fsize); + correct = False; + } + + if (!cli_unlink(&cli1, lockfname)) { + printf("unlink failed (%s)\n", cli_errstr(&cli1)); + correct = False; + } + + fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE); + if (fnum1 == -1) { + printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1)); + return False; + } + + cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf)); + + if (!cli_close(&cli1, fnum1)) { + printf("close failed (%s)\n", cli_errstr(&cli1)); + correct = False; + } + + if (!close_connection(&cli1)) { + correct = False; + } + return correct; + } + int line_count = 0; /* run a test that simulates an approximate netbench client load */ -static void run_netbench(int client) +static BOOL run_netbench(int client) { struct cli_state cli; int i; @@ -497,6 +608,7 @@ static void run_netbench(int client) char cname[20]; FILE *f; char *params[20]; + BOOL correct = True; cli = current_cli; @@ -510,7 +622,7 @@ static void run_netbench(int client) if (!f) { perror("client.txt"); - return; + return False; } while (fgets(line, sizeof(line)-1, f)) { @@ -584,15 +696,20 @@ static void run_netbench(int client) printf("+"); - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } + + return correct; } /* run a test that simulates an approximate netbench w9X client load */ -static void run_nbw95(int dummy) +static BOOL run_nbw95(int dummy) { double t; - t = create_procs(run_netbench); + BOOL correct = True; + t = create_procs(run_netbench, &correct); /* to produce a netbench result we scale accoding to the netbench measured throughput for the run that produced the sniff that was used to produce client.txt. That run used 2 @@ -600,15 +717,18 @@ static void run_nbw95(int dummy) 4MBit/sec. */ printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n", 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t); + return correct; } /* run a test that simulates an approximate netbench wNT client load */ -static void run_nbwnt(int dummy) +static BOOL run_nbwnt(int dummy) { double t; - t = create_procs(run_netbench); + BOOL correct = True; + t = create_procs(run_netbench, &correct); printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n", 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t); + return correct; } @@ -620,7 +740,7 @@ static void run_nbwnt(int dummy) must not use posix semantics) 2) support for lock timeouts */ -static void run_locktest1(int dummy) +static BOOL run_locktest1(int dummy) { static struct cli_state cli1, cli2; char *fname = "\\lockt1.lck"; @@ -628,7 +748,7 @@ static void run_locktest1(int dummy) time_t t1, t2; if (!open_connection(&cli1) || !open_connection(&cli2)) { - return; + return False; } cli_sockopt(&cli1, sockops); cli_sockopt(&cli2, sockops); @@ -640,30 +760,30 @@ static void run_locktest1(int dummy) fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum1 == -1) { printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE); if (fnum2 == -1) { printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE); if (fnum3 == -1) { printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2)); - return; + return False; } if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) { printf("lock1 failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) { printf("lock2 succeeded! This is a locking bug\n"); - return; + return False; } else { - if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return; + if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False; } @@ -671,9 +791,9 @@ static void run_locktest1(int dummy) t1 = time(NULL); if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) { printf("lock3 succeeded! This is a locking bug\n"); - return; + return False; } else { - if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return; + if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False; } t2 = time(NULL); @@ -683,42 +803,48 @@ static void run_locktest1(int dummy) if (!cli_close(&cli1, fnum2)) { printf("close1 failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) { printf("lock4 succeeded! This is a locking bug\n"); - return; + return False; } else { - if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return; + if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False; } if (!cli_close(&cli1, fnum1)) { printf("close2 failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } if (!cli_close(&cli2, fnum3)) { printf("close3 failed (%s)\n", cli_errstr(&cli2)); - return; + return False; } if (!cli_unlink(&cli1, fname)) { printf("unlink failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } - close_connection(&cli1); - close_connection(&cli2); + if (!close_connection(&cli1)) { + return False; + } + + if (!close_connection(&cli2)) { + return False; + } printf("Passed locktest1\n"); + return True; } /* checks for correct tconX support */ -static void run_tcon_test(int dummy) +static BOOL run_tcon_test(int dummy) { static struct cli_state cli1; char *fname = "\\tcontest.tmp"; @@ -727,7 +853,7 @@ static void run_tcon_test(int dummy) char buf[4]; if (!open_connection(&cli1)) { - return; + return False; } cli_sockopt(&cli1, sockops); @@ -739,7 +865,7 @@ static void run_tcon_test(int dummy) if (fnum1 == -1) { printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } cnum = cli1.cnum; @@ -747,7 +873,7 @@ static void run_tcon_test(int dummy) if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) { printf("write failed (%s)", cli_errstr(&cli1)); - return; + return False; } if (!cli_send_tconX(&cli1, share, "?????", @@ -755,35 +881,38 @@ static void run_tcon_test(int dummy) printf("%s refused 2nd tree connect (%s)\n", host, cli_errstr(&cli1)); cli_shutdown(&cli1); - return ; + return False; } if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4) { printf("write succeeded (%s)", cli_errstr(&cli1)); - return; + return False; } if (cli_close(&cli1, fnum1)) { printf("close2 succeeded (%s)\n", cli_errstr(&cli1)); - return; + return False; } if (!cli_tdis(&cli1)) { printf("tdis failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } cli1.cnum = cnum; if (!cli_close(&cli1, fnum1)) { printf("close2 failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } - close_connection(&cli1); + if (!close_connection(&cli1)) { + return False; + } printf("Passed tcontest\n"); + return True; } @@ -798,14 +927,15 @@ static void run_tcon_test(int dummy) 3) the server denies unlock requests by an incorrect client PID */ -static void run_locktest2(int dummy) +static BOOL run_locktest2(int dummy) { static struct cli_state cli; char *fname = "\\lockt2.lck"; int fnum1, fnum2, fnum3; + BOOL correct = True; if (!open_connection(&cli)) { - return; + return False; } cli_sockopt(&cli, sockops); @@ -819,13 +949,13 @@ static void run_locktest2(int dummy) 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; + return False; } fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE); if (fnum2 == -1) { printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli)); - return; + return False; } cli_setpid(&cli, 2); @@ -833,66 +963,89 @@ static void run_locktest2(int dummy) fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE); if (fnum3 == -1) { printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli)); - return; + return False; } cli_setpid(&cli, 1); if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) { printf("lock1 failed (%s)\n", cli_errstr(&cli)); - return; + return False; } if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) { printf("WRITE lock1 succeeded! This is a locking bug\n"); + correct = False; } else { - if (!check_error(&cli, ERRDOS, ERRlock, 0)) return; + if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False; } if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) { printf("WRITE lock2 succeeded! This is a locking bug\n"); + correct = False; } else { - if (!check_error(&cli, ERRDOS, ERRlock, 0)) return; + if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False; } if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) { printf("READ lock2 succeeded! This is a locking bug\n"); + correct = False; } else { - if (!check_error(&cli, ERRDOS, ERRlock, 0)) return; + if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False; } + if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) { + printf("lock at 100 failed (%s)\n", cli_errstr(&cli)); + } cli_setpid(&cli, 2); + if (cli_unlock(&cli, fnum1, 100, 4)) { + printf("unlock at 100 succeeded! This is a locking bug\n"); + correct = False; + } - if (cli_unlock(&cli, fnum1, 0, 8)) { + if (cli_unlock(&cli, fnum1, 0, 4)) { printf("unlock1 succeeded! This is a locking bug\n"); + } else { + if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False; + } + + if (cli_unlock(&cli, fnum1, 0, 8)) { + printf("unlock2 succeeded! This is a locking bug\n"); + } else { + if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False; } if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) { printf("lock3 succeeded! This is a locking bug\n"); + correct = False; } else { - if (!check_error(&cli, ERRDOS, ERRlock, 0)) return; + if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False; } cli_setpid(&cli, 1); if (!cli_close(&cli, fnum1)) { printf("close1 failed (%s)\n", cli_errstr(&cli)); - return; + return False; } if (!cli_close(&cli, fnum2)) { printf("close2 failed (%s)\n", cli_errstr(&cli)); - return; + return False; } if (!cli_close(&cli, fnum3)) { printf("close3 failed (%s)\n", cli_errstr(&cli)); - return; + return False; } - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("locktest2 finished\n"); + + return correct; } @@ -901,17 +1054,18 @@ static void run_locktest2(int dummy) 1) the server supports the full offset range in lock requests */ -static void run_locktest3(int dummy) +static BOOL run_locktest3(int dummy) { static struct cli_state cli1, cli2; char *fname = "\\lockt3.lck"; int fnum1, fnum2, i; uint32 offset; + BOOL correct = True; #define NEXT_OFFSET offset += (~(uint32)0) / numops if (!open_connection(&cli1) || !open_connection(&cli2)) { - return; + return False; } cli_sockopt(&cli1, sockops); cli_sockopt(&cli2, sockops); @@ -923,12 +1077,12 @@ static void run_locktest3(int dummy) fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum1 == -1) { printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE); if (fnum2 == -1) { printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2)); - return; + return False; } for (offset=i=0;i<numops;i++) { @@ -937,14 +1091,14 @@ static void run_locktest3(int dummy) printf("lock1 %d failed (%s)\n", i, cli_errstr(&cli1)); - return; + return False; } if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) { printf("lock2 %d failed (%s)\n", i, cli_errstr(&cli1)); - return; + return False; } } @@ -953,22 +1107,22 @@ static void run_locktest3(int dummy) if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) { printf("error: lock1 %d succeeded!\n", i); - return; + return False; } if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) { printf("error: lock2 %d succeeded!\n", i); - return; + return False; } if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) { printf("error: lock3 %d succeeded!\n", i); - return; + return False; } if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) { printf("error: lock4 %d succeeded!\n", i); - return; + return False; } } @@ -979,51 +1133,63 @@ static void run_locktest3(int dummy) printf("unlock1 %d failed (%s)\n", i, cli_errstr(&cli1)); - return; + return False; } if (!cli_unlock(&cli2, fnum2, offset-2, 1)) { printf("unlock2 %d failed (%s)\n", i, cli_errstr(&cli1)); - return; + return False; } } if (!cli_close(&cli1, fnum1)) { printf("close1 failed (%s)\n", cli_errstr(&cli1)); + return False; } if (!cli_close(&cli2, fnum2)) { printf("close2 failed (%s)\n", cli_errstr(&cli2)); + return False; } if (!cli_unlink(&cli1, fname)) { printf("unlink failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } - close_connection(&cli1); - close_connection(&cli2); + if (!close_connection(&cli1)) { + correct = False; + } + + if (!close_connection(&cli2)) { + correct = False; + } printf("finished locktest3\n"); + + return correct; } -#define EXPECTED(ret, v) if ((ret) != (v)) printf("** ") +#define EXPECTED(ret, v) if ((ret) != (v)) { \ + printf("** "); correct = False; \ + } /* looks at overlapping locks */ -static void run_locktest4(int dummy) +static BOOL run_locktest4(int dummy) { static struct cli_state cli1, cli2; char *fname = "\\lockt4.lck"; int fnum1, fnum2, f; BOOL ret; char buf[1000]; + BOOL correct = True; if (!open_connection(&cli1) || !open_connection(&cli2)) { - return; + return False; } cli_sockopt(&cli1, sockops); @@ -1040,6 +1206,7 @@ static void run_locktest4(int dummy) if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) { printf("Failed to create file\n"); + correct = False; goto fail; } @@ -1168,8 +1335,6 @@ static void run_locktest4(int dummy) EXPECTED(ret, True); printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't"); - - fail: cli_close(&cli1, fnum1); cli_close(&cli2, fnum2); @@ -1178,21 +1343,23 @@ static void run_locktest4(int dummy) close_connection(&cli2); printf("finished locktest4\n"); + return correct; } /* looks at lock upgrade/downgrade. */ -static void run_locktest5(int dummy) +static BOOL run_locktest5(int dummy) { static struct cli_state cli1, cli2; char *fname = "\\lockt5.lck"; int fnum1, fnum2, fnum3; BOOL ret; char buf[1000]; + BOOL correct = True; if (!open_connection(&cli1) || !open_connection(&cli2)) { - return; + return False; } cli_sockopt(&cli1, sockops); @@ -1210,6 +1377,7 @@ static void run_locktest5(int dummy) if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) { printf("Failed to create file\n"); + correct = False; goto fail; } @@ -1285,21 +1453,28 @@ static void run_locktest5(int dummy) printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot"); + fail: cli_close(&cli1, fnum1); cli_close(&cli2, fnum2); cli_unlink(&cli1, fname); - close_connection(&cli1); - close_connection(&cli2); + if (!close_connection(&cli1)) { + correct = False; + } + if (!close_connection(&cli2)) { + correct = False; + } printf("finished locktest5\n"); + + return correct; } /* this produces a matrix of deny mode behaviour */ -static void run_denytest1(int dummy) +static BOOL run_denytest1(int dummy) { static struct cli_state cli1, cli2; int fnum1, fnum2; @@ -1324,9 +1499,10 @@ static void run_denytest1(int dummy) {O_RDONLY, "O_RDONLY"}, {O_WRONLY, "O_WRONLY"}, {-1, NULL}}; + BOOL correct = True; if (!open_connection(&cli1) || !open_connection(&cli2)) { - return; + return False; } cli_sockopt(&cli1, sockops); cli_sockopt(&cli2, sockops); @@ -1379,10 +1555,15 @@ static void run_denytest1(int dummy) cli_unlink(&cli1, fnames[f]); } - close_connection(&cli1); - close_connection(&cli2); + if (!close_connection(&cli1)) { + correct = False; + } + if (!close_connection(&cli2)) { + correct = False; + } printf("finshed denytest1\n"); + return correct; } @@ -1390,7 +1571,7 @@ static void run_denytest1(int dummy) this produces a matrix of deny mode behaviour for two opens on the same connection */ -static void run_denytest2(int dummy) +static BOOL run_denytest2(int dummy) { static struct cli_state cli1; int fnum1, fnum2; @@ -1415,9 +1596,10 @@ static void run_denytest2(int dummy) {O_RDONLY, "O_RDONLY"}, {O_WRONLY, "O_WRONLY"}, {-1, NULL}}; + BOOL correct = True; if (!open_connection(&cli1)) { - return; + return False; } cli_sockopt(&cli1, sockops); @@ -1469,16 +1651,19 @@ static void run_denytest2(int dummy) cli_unlink(&cli1, fnames[f]); } - close_connection(&cli1); + if (!close_connection(&cli1)) { + correct = False; + } printf("finshed denytest2\n"); + return correct; } /* test whether fnums and tids open on one VC are available on another (a major security hole) */ -static void run_fdpasstest(int dummy) +static BOOL run_fdpasstest(int dummy) { static struct cli_state cli1, cli2, cli3; char *fname = "\\fdpass.tst"; @@ -1486,7 +1671,7 @@ static void run_fdpasstest(int dummy) pstring buf; if (!open_connection(&cli1) || !open_connection(&cli2)) { - return; + return False; } cli_sockopt(&cli1, sockops); cli_sockopt(&cli2, sockops); @@ -1498,12 +1683,12 @@ static void run_fdpasstest(int dummy) fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum1 == -1) { printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) { printf("write failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } cli3 = cli2; @@ -1514,7 +1699,7 @@ static void run_fdpasstest(int dummy) if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) { printf("read succeeded! nasty security hole [%s]\n", buf); - return; + return False; } cli_close(&cli1, fnum1); @@ -1524,6 +1709,7 @@ static void run_fdpasstest(int dummy) close_connection(&cli2); printf("finished fdpasstest\n"); + return True; } @@ -1532,14 +1718,15 @@ static void run_fdpasstest(int dummy) 1) the server does not allow an unlink on a file that is open */ -static void run_unlinktest(int dummy) +static BOOL run_unlinktest(int dummy) { static struct cli_state cli; char *fname = "\\unlink.tst"; int fnum; + BOOL correct = True; if (!open_connection(&cli)) { - return; + return False; } cli_sockopt(&cli, sockops); @@ -1553,38 +1740,44 @@ static void run_unlinktest(int dummy) fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum == -1) { printf("open of %s failed (%s)\n", fname, cli_errstr(&cli)); - return; + return False; } if (cli_unlink(&cli, fname)) { printf("error: server allowed unlink on an open file\n"); + correct = False; } cli_close(&cli, fnum); cli_unlink(&cli, fname); - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("unlink test finished\n"); + + return correct; } /* test how many open files this server supports on the one socket */ -static void run_maxfidtest(int dummy) +static BOOL run_maxfidtest(int dummy) { static struct cli_state cli; char *template = "\\maxfid.%d.%d"; fstring fname; int fnum; int retries=4; + BOOL correct = True; cli = current_cli; if (retries <= 0) { printf("failed to connect\n"); - return; + return False; } cli_sockopt(&cli, sockops); @@ -1613,11 +1806,15 @@ static void run_maxfidtest(int dummy) if (!cli_unlink(&cli, fname)) { printf("unlink of %s failed (%s)\n", fname, cli_errstr(&cli)); + correct = False; } } printf("maxfid test finished\n"); - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } + return correct; } /* generate a random buffer */ @@ -1630,29 +1827,34 @@ static void rand_buf(char *buf, int len) } /* send smb negprot commands, not reading the response */ -static void run_negprot_nowait(int dummy) +static BOOL run_negprot_nowait(int dummy) { int i; static struct cli_state cli; + BOOL correct = True; printf("starting negprot nowait test\n"); if (!open_nbt_connection(&cli)) { - return; + return False; } for (i=0;i<50000;i++) { cli_negprot_send(&cli); } - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("finished negprot nowait test\n"); + + return correct; } /* send random IPC commands */ -static void run_randomipc(int dummy) +static BOOL run_randomipc(int dummy) { char *rparam = NULL; char *rdata = NULL; @@ -1660,11 +1862,12 @@ static void run_randomipc(int dummy) pstring param; int api, param_len, i; static struct cli_state cli; + BOOL correct = True; printf("starting random ipc test\n"); if (!open_connection(&cli)) { - return; + return False; } for (i=0;i<50000;i++) { @@ -1682,15 +1885,19 @@ static void run_randomipc(int dummy) &rdata, &rdrcnt); } - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("finished random ipc test\n"); + + return correct; } static void browse_callback(const char *sname, uint32 stype, - const char *comment) + const char *comment, void *state) { printf("\t%20.20s %08x %s\n", sname, stype, comment); } @@ -1701,46 +1908,53 @@ static void browse_callback(const char *sname, uint32 stype, This test checks the browse list code */ -static void run_browsetest(int dummy) +static BOOL run_browsetest(int dummy) { static struct cli_state cli; + BOOL correct = True; printf("starting browse test\n"); if (!open_connection(&cli)) { - return; + return False; } printf("domain list:\n"); cli_NetServerEnum(&cli, cli.server_domain, SV_TYPE_DOMAIN_ENUM, - browse_callback); + browse_callback, NULL); printf("machine list:\n"); cli_NetServerEnum(&cli, cli.server_domain, SV_TYPE_ALL, - browse_callback); + browse_callback, NULL); - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("browse test finished\n"); + + return correct; + } /* This checks how the getatr calls works */ -static void run_attrtest(int dummy) +static BOOL run_attrtest(int dummy) { static struct cli_state cli; int fnum; time_t t, t2; char *fname = "\\attrib.tst"; + BOOL correct = True; printf("starting attrib test\n"); if (!open_connection(&cli)) { - return; + return False; } cli_unlink(&cli, fname); @@ -1749,42 +1963,51 @@ static void run_attrtest(int dummy) cli_close(&cli, fnum); if (!cli_getatr(&cli, fname, NULL, NULL, &t)) { printf("getatr failed (%s)\n", cli_errstr(&cli)); + correct = False; } if (abs(t - time(NULL)) > 2) { printf("ERROR: SMBgetatr bug. time is %s", ctime(&t)); t = time(NULL); + correct = True; } t2 = t-60*60*24; /* 1 day ago */ if (!cli_setatr(&cli, fname, 0, t2)) { printf("setatr failed (%s)\n", cli_errstr(&cli)); + correct = True; } if (!cli_getatr(&cli, fname, NULL, NULL, &t)) { printf("getatr failed (%s)\n", cli_errstr(&cli)); + correct = True; } if (t != t2) { printf("ERROR: getatr/setatr bug. times are\n%s", ctime(&t)); printf("%s", ctime(&t2)); + correct = True; } cli_unlink(&cli, fname); - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("attrib test finished\n"); + + return correct; } /* This checks a couple of trans2 calls */ -static void run_trans2test(int dummy) +static BOOL run_trans2test(int dummy) { static struct cli_state cli; int fnum; @@ -1793,11 +2016,12 @@ static void run_trans2test(int dummy) char *fname = "\\trans2.tst"; char *dname = "\\trans2"; char *fname2 = "\\trans2\\trans2.tst"; + BOOL correct = True; printf("starting trans2 test\n"); if (!open_connection(&cli)) { - return; + return False; } cli_unlink(&cli, fname); @@ -1806,6 +2030,7 @@ static void run_trans2test(int dummy) if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time, NULL, NULL)) { printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli)); + correct = False; } cli_close(&cli, fnum); @@ -1818,19 +2043,23 @@ static void run_trans2test(int dummy) if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) { printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli)); + correct = False; } else { if (c_time != m_time) { printf("create time=%s", ctime(&c_time)); printf("modify time=%s", ctime(&m_time)); printf("This system appears to have sticky create times\n"); + correct = False; } if (a_time % (60*60) == 0) { printf("access time=%s", ctime(&a_time)); printf("This system appears to set a midnight access time\n"); + correct = False; } if (abs(m_time - time(NULL)) > 60*60*24*7) { printf("ERROR: totally incorrect times - maybe word reversed?\n"); + correct = False; } } @@ -1842,10 +2071,12 @@ static void run_trans2test(int dummy) if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL)) { printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)); + correct = False; } else { if (w_time < 60*60*24*2) { printf("write time=%s", ctime(&w_time)); printf("This system appears to set a initial 0 write time\n"); + correct = False; } } @@ -1856,11 +2087,13 @@ static void run_trans2test(int dummy) when creating a new file */ if (!cli_mkdir(&cli, dname)) { printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli)); + correct = False; } sleep(3); if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL)) { printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)); + correct = False; } fnum = cli_open(&cli, fname2, @@ -1870,33 +2103,96 @@ static void run_trans2test(int dummy) if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL)) { printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)); + correct = False; } else { - if (m_time2 == m_time) + if (m_time2 == m_time) { printf("This system does not update directory modification times\n"); + correct = False; + } } cli_unlink(&cli, fname2); cli_rmdir(&cli, dname); - - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("trans2 test finished\n"); + + return correct; +} + +/* + This checks new W2K calls. +*/ + +static BOOL new_trans(struct cli_state *pcli, int fnum, int level) +{ + char buf[4096]; + BOOL correct = True; + + memset(buf, 0xff, sizeof(buf)); + + if (!cli_qfileinfo_test(pcli, fnum, level, buf)) { + printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli)); + correct = False; + } else { + printf("qfileinfo: level %d\n", level); + dump_data(0, buf, 256); + printf("\n"); + } + return correct; +} + +static BOOL run_w2ktest(int dummy) +{ + static struct cli_state cli; + int fnum; + char *fname = "\\w2ktest\\w2k.tst"; + int level; + BOOL correct = True; + + printf("starting w2k test\n"); + + if (!open_connection(&cli)) { + return False; + } + + fnum = cli_open(&cli, fname, + O_RDWR | O_CREAT , DENY_NONE); + + for (level = 1004; level < 1040; level++) { + if (!new_trans(&cli, fnum, level)) { + correct = False; + } + } + + cli_close(&cli, fnum); + + if (!close_connection(&cli)) { + correct = False; + } + + printf("w2k test finished\n"); + + return correct; } /* this is a harness for some oplock tests */ -static void run_oplock1(int dummy) +static BOOL run_oplock1(int dummy) { static struct cli_state cli1; char *fname = "\\lockt1.lck"; int fnum1; + BOOL correct = True; printf("starting oplock test 1\n"); if (!open_connection(&cli1)) { - return; + return False; } cli_unlink(&cli1, fname); @@ -1908,7 +2204,7 @@ static void run_oplock1(int dummy) fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum1 == -1) { printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } cli1.use_oplocks = False; @@ -1918,27 +2214,35 @@ static void run_oplock1(int dummy) if (!cli_close(&cli1, fnum1)) { printf("close2 failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } if (!cli_unlink(&cli1, fname)) { printf("unlink failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } - - close_connection(&cli1); + if (!close_connection(&cli1)) { + correct = False; + } printf("finished oplock test 1\n"); + + return correct; } -static void run_oplock2(int dummy) +static BOOL run_oplock2(int dummy) { static struct cli_state cli1, cli2; char *fname = "\\lockt2.lck"; int fnum1, fnum2; int saved_use_oplocks = use_oplocks; char buf[4]; + BOOL correct = True; + volatile BOOL *shared_correct; + + shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL)); + *shared_correct = True; use_level_II_oplocks = True; use_oplocks = True; @@ -1948,7 +2252,7 @@ static void run_oplock2(int dummy) if (!open_connection(&cli1)) { use_level_II_oplocks = False; use_oplocks = saved_use_oplocks; - return; + return False; } cli1.use_oplocks = True; @@ -1957,7 +2261,7 @@ static void run_oplock2(int dummy) if (!open_connection(&cli2)) { use_level_II_oplocks = False; use_oplocks = saved_use_oplocks; - return; + return False; } cli2.use_oplocks = True; @@ -1971,7 +2275,7 @@ static void run_oplock2(int dummy) fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum1 == -1) { printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } /* Don't need the globals any more. */ @@ -1983,6 +2287,7 @@ static void run_oplock2(int dummy) fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE); if (fnum2 == -1) { printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1)); + *shared_correct = False; exit(0); } @@ -1990,6 +2295,7 @@ static void run_oplock2(int dummy) if (!cli_close(&cli2, fnum2)) { printf("close2 failed (%s)\n", cli_errstr(&cli1)); + *shared_correct = False; } exit(0); @@ -2001,6 +2307,7 @@ static void run_oplock2(int dummy) if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) { printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1)); + correct = False; } /* Should now be at level II. */ @@ -2008,6 +2315,7 @@ static void run_oplock2(int dummy) if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) { printf("lock failed (%s)\n", cli_errstr(&cli1)); + correct = False; } cli_unlock(&cli1, fnum1, 0, 4); @@ -2016,6 +2324,7 @@ static void run_oplock2(int dummy) if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) { printf("lock failed (%s)\n", cli_errstr(&cli1)); + correct = False; } cli_unlock(&cli1, fnum1, 0, 4); @@ -2027,107 +2336,121 @@ static void run_oplock2(int dummy) #if 0 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) { printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1)); + correct = False; } #endif if (!cli_close(&cli1, fnum1)) { printf("close1 failed (%s)\n", cli_errstr(&cli1)); + correct = False; } sleep(4); if (!cli_unlink(&cli1, fname)) { printf("unlink failed (%s)\n", cli_errstr(&cli1)); + correct = False; } - close_connection(&cli1); + if (!close_connection(&cli1)) { + correct = False; + } + + if (!*shared_correct) { + correct = False; + } printf("finished oplock test 2\n"); + + return correct; } + /* Test delete on close semantics. */ -static void run_deletetest(int dummy) +static BOOL run_deletetest(int dummy) { - static struct cli_state cli1; - static struct cli_state cli2; - char *fname = "\\delete.file"; - int fnum1, fnum2; - - printf("starting delete test\n"); - - if (!open_connection(&cli1)) { - return; - } - + static struct cli_state cli1; + static struct cli_state cli2; + char *fname = "\\delete.file"; + int fnum1, fnum2; + BOOL correct = True; + + printf("starting delete test\n"); + + if (!open_connection(&cli1)) { + return False; + } + cli_sockopt(&cli1, sockops); - + /* Test 1 - this should *NOT* delete the file on close. */ - + 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_DELETE, FILE_OVERWRITE_IF, DELETE_ON_CLOSE_FLAG); - + FILE_SHARE_DELETE, FILE_OVERWRITE_IF, DELETE_ON_CLOSE_FLAG); + if (fnum1 == -1) { printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("[1] close failed (%s)\n", cli_errstr(&cli1)); + return False; } - if (!cli_close(&cli1, fnum1)) { - printf("[1] close failed (%s)\n", cli_errstr(&cli1)); - return; - } - - fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE); - if (fnum1 == -1) { - printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("[1] close failed (%s)\n", cli_errstr(&cli1)); - return; - } - + fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE); + if (fnum1 == -1) { + printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("[1] close failed (%s)\n", cli_errstr(&cli1)); + return False; + } + printf("first delete on close test succeeded.\n"); - + /* Test 2 - this should delete the file on close. */ - + 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_NONE, FILE_OVERWRITE_IF, 0); - + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0); + if (fnum1 == -1) { printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } - + if (!cli_nt_delete_on_close(&cli1, fnum1, True)) { - printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1)); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("[2] close failed (%s)\n", cli_errstr(&cli1)); - return; - } - - fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); - if (fnum1 != -1) { + printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1)); + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("[2] close failed (%s)\n", cli_errstr(&cli1)); + return False; + } + + fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); + if (fnum1 != -1) { printf("[2] open of %s succeeded should have been deleted on close !\n", fname); if (!cli_close(&cli1, fnum1)) { printf("[2] close failed (%s)\n", cli_errstr(&cli1)); + correct = False; } cli_unlink(&cli1, fname); - } else + } else printf("second delete on close test succeeded.\n"); - - + + /* Test 3 - ... */ cli_setatr(&cli1, fname, 0, 0); cli_unlink(&cli1, fname); @@ -2137,7 +2460,7 @@ static void run_deletetest(int dummy) if (fnum1 == -1) { printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } /* This should fail with a sharing violation - open for delete is only compatible @@ -2148,7 +2471,7 @@ static void run_deletetest(int dummy) if (fnum2 != -1) { printf("[3] open - 2 of %s succeeded - should have failed.\n", fname); - return; + return False; } /* This should succeed. */ @@ -2158,34 +2481,35 @@ static void run_deletetest(int dummy) if (fnum2 == -1) { printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } if (!cli_nt_delete_on_close(&cli1, fnum1, True)) { - printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1)); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1)); - return; - } - - if (!cli_close(&cli1, fnum2)) { - printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1)); - return; - } - + printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1)); + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + + if (!cli_close(&cli1, fnum2)) { + printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + /* This should fail - file should no longer be there. */ - fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); - if (fnum1 != -1) { + fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); + if (fnum1 != -1) { printf("[3] open of %s succeeded should have been deleted on close !\n", fname); if (!cli_close(&cli1, fnum1)) { printf("[3] close failed (%s)\n", cli_errstr(&cli1)); } cli_unlink(&cli1, fname); - } else + correct = False; + } else printf("third delete on close test succeeded.\n"); /* Test 4 ... */ @@ -2197,7 +2521,7 @@ static void run_deletetest(int dummy) if (fnum1 == -1) { printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } /* This should succeed. */ @@ -2205,346 +2529,373 @@ static void run_deletetest(int dummy) FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); if (fnum2 == -1) { printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } - - if (!cli_close(&cli1, fnum2)) { - printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1)); - return; - } - + + if (!cli_close(&cli1, fnum2)) { + printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + if (!cli_nt_delete_on_close(&cli1, fnum1, True)) { - printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1)); - return; - } - + printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1)); + return False; + } + /* 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); + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); if (fnum2 != -1) { printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname ); - return; - } else + return False; + } else printf("fourth delete on close test succeeded.\n"); - - if (!cli_close(&cli1, fnum1)) { - printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1)); - return; - } - + + if (!cli_close(&cli1, fnum1)) { + printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + /* Test 5 ... */ cli_setatr(&cli1, fname, 0, 0); cli_unlink(&cli1, fname); - - fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE); + + fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum1 == -1) { printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } /* This should fail - only allowed on NT opens with DELETE access. */ if (cli_nt_delete_on_close(&cli1, fnum1, True)) { - printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n"); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1)); - return; - } + printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n"); + return False; + } + if (!cli_close(&cli1, fnum1)) { + printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + printf("fifth delete on close test succeeded.\n"); - + /* Test 6 ... */ cli_setatr(&cli1, fname, 0, 0); cli_unlink(&cli1, fname); - + fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - FILE_OVERWRITE_IF, 0); - + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OVERWRITE_IF, 0); + if (fnum1 == -1) { printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } - + /* This should fail - only allowed on NT opens with DELETE access. */ - + if (cli_nt_delete_on_close(&cli1, fnum1, True)) { - printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n"); - return; - } + printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n"); + return False; + } - if (!cli_close(&cli1, fnum1)) { - printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1)); - return; - } + if (!cli_close(&cli1, fnum1)) { + printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } printf("sixth delete on close test succeeded.\n"); - + /* Test 7 ... */ 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); + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0); if (fnum1 == -1) { printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } if (!cli_nt_delete_on_close(&cli1, fnum1, True)) { - printf("[7] setting delete_on_close on file failed !\n"); - return; - } - + printf("[7] setting delete_on_close on file failed !\n"); + return False; + } + if (!cli_nt_delete_on_close(&cli1, fnum1, False)) { - printf("[7] unsetting delete_on_close on file failed !\n"); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1)); - return; - } + printf("[7] unsetting delete_on_close on file failed !\n"); + return False; + } + if (!cli_close(&cli1, fnum1)) { + printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + /* This next open should succeed - we reset the flag. */ - - fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); + + fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); if (fnum1 == -1) { printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } - if (!cli_close(&cli1, fnum1)) { - printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1)); - return; - } + if (!cli_close(&cli1, fnum1)) { + printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } printf("seventh delete on close test succeeded.\n"); - + /* Test 7 ... */ cli_setatr(&cli1, fname, 0, 0); cli_unlink(&cli1, fname); - - if (!open_connection(&cli2)) { + + if (!open_connection(&cli2)) { printf("[8] failed to open second connection.\n"); - return; - } + return False; + } 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); - + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0); + if (fnum1 == -1) { printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } 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); - + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0); + if (fnum2 == -1) { printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; + return False; } if (!cli_nt_delete_on_close(&cli1, fnum1, True)) { - printf("[8] setting delete_on_close on file failed !\n"); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1)); - return; - } + printf("[8] setting delete_on_close on file failed !\n"); + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1)); + return False; + } - if (!cli_close(&cli2, fnum2)) { - printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2)); - return; - } + if (!cli_close(&cli2, fnum2)) { + printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2)); + return False; + } /* This should fail.. */ - fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); - if (fnum1 != -1) { + fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE); + if (fnum1 != -1) { printf("[8] open of %s succeeded should have been deleted on close !\n", fname); if (!cli_close(&cli1, fnum1)) { printf("[8] close failed (%s)\n", cli_errstr(&cli1)); } cli_unlink(&cli1, fname); - } else + correct = False; + } else printf("eighth delete on close test succeeded.\n"); - printf("finished delete test\n"); - + printf("finished delete test\n"); + cli_setatr(&cli1, fname, 0, 0); cli_unlink(&cli1, fname); - - close_connection(&cli1); - close_connection(&cli2); + + if (!close_connection(&cli1)) { + correct = False; + } + if (!close_connection(&cli2)) { + correct = False; + } + return correct; } /* Test open mode returns on read-only files. */ -static void run_opentest(int dummy) +static BOOL run_opentest(int dummy) { - static struct cli_state cli1; - char *fname = "\\readonly.file"; - int fnum1, fnum2; + static struct cli_state cli1; + char *fname = "\\readonly.file"; + int fnum1, fnum2; uint8 eclass; uint32 errnum; char buf[20]; size_t fsize; + BOOL correct = True; - printf("starting open test\n"); - - if (!open_connection(&cli1)) { - return; - } - + printf("starting open test\n"); + + if (!open_connection(&cli1)) { + return False; + } + cli_setatr(&cli1, fname, 0, 0); - cli_unlink(&cli1, fname); - - cli_sockopt(&cli1, sockops); - - fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); - if (fnum1 == -1) { - printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("close2 failed (%s)\n", cli_errstr(&cli1)); - return; - } + cli_unlink(&cli1, fname); + + cli_sockopt(&cli1, sockops); + + fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); + if (fnum1 == -1) { + printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + if (!cli_close(&cli1, fnum1)) { + printf("close2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + if (!cli_setatr(&cli1, fname, aRONLY, 0)) { printf("cli_setatr failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } - - fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE); - if (fnum1 == -1) { - printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; - } - + + fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE); + if (fnum1 == -1) { + printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */ - fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL); - + fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL); + cli_error( &cli1, &eclass, &errnum, NULL); - + if (eclass != ERRDOS || errnum != ERRnoaccess) { printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass, - (unsigned int)errnum, cli_errstr(&cli1) ); + (unsigned int)errnum, cli_errstr(&cli1) ); + correct = False; } else { printf("correct error code ERRDOS/ERRnoaccess returned\n"); } - - printf("finished open test 1\n"); - + + printf("finished open test 1\n"); + cli_close(&cli1, fnum1); - + /* Now try not readonly and ensure ERRbadshare is returned. */ - + cli_setatr(&cli1, fname, 0, 0); - - fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE); - if (fnum1 == -1) { - printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; - } - + + fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE); + if (fnum1 == -1) { + printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + /* This will fail - but the error should be ERRshare. */ - fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL); - + fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL); + cli_error( &cli1, &eclass, &errnum, NULL); if (eclass != ERRDOS || errnum != ERRbadshare) { printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass, - (unsigned int)errnum, cli_errstr(&cli1) ); + (unsigned int)errnum, cli_errstr(&cli1) ); + correct = False; } else { printf("correct error code ERRDOS/ERRbadshare returned\n"); } - - if (!cli_close(&cli1, fnum1)) { - printf("close2 failed (%s)\n", cli_errstr(&cli1)); - return; - } - + + if (!cli_close(&cli1, fnum1)) { + printf("close2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + cli_unlink(&cli1, fname); - - printf("finished open test 2\n"); - + + printf("finished open test 2\n"); + /* Test truncate open disposition on file opened for read. */ - - fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); - if (fnum1 == -1) { - printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; - } - + + fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); + if (fnum1 == -1) { + printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + /* write 20 bytes. */ - + memset(buf, '\0', 20); if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) { printf("write failed (%s)\n", cli_errstr(&cli1)); + correct = False; } - if (!cli_close(&cli1, fnum1)) { - printf("(3) close1 failed (%s)\n", cli_errstr(&cli1)); - return; - } - + if (!cli_close(&cli1, fnum1)) { + printf("(3) close1 failed (%s)\n", cli_errstr(&cli1)); + return False; + } + /* Ensure size == 20. */ if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) { printf("(3) getatr failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } - + if (fsize != 20) { printf("(3) file size != 20\n"); - return; + return False; } /* Now test if we can truncate a file opened for readonly. */ - + fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE); - if (fnum1 == -1) { - printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1)); - return; - } - - if (!cli_close(&cli1, fnum1)) { - printf("close2 failed (%s)\n", cli_errstr(&cli1)); - return; - } + if (fnum1 == -1) { + printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1)); + return False; + } + + if (!cli_close(&cli1, fnum1)) { + printf("close2 failed (%s)\n", cli_errstr(&cli1)); + return False; + } /* Ensure size == 0. */ if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) { printf("(3) getatr failed (%s)\n", cli_errstr(&cli1)); - return; + return False; } if (fsize != 0) { printf("(3) file size != 0\n"); - return; + return False; } - printf("finished open test 3\n"); - + printf("finished open test 3\n"); + cli_unlink(&cli1, fname); - close_connection(&cli1); + printf("testing ctemp\n"); + { + char *tmp_path; + fnum1 = cli_ctemp(&cli1, "\\", &tmp_path); + if (fnum1 == -1) { + printf("ctemp failed (%s)\n", cli_errstr(&cli1)); + return False; + } + printf("ctemp gave path %s\n", tmp_path); + cli_close(&cli1, fnum1); + cli_unlink(&cli1, tmp_path); + } + + if (!close_connection(&cli1)) { + correct = False; + } + + return correct; } -static void list_fn(file_info *finfo, const char *name) +static void list_fn(file_info *finfo, const char *name, void *state) { } @@ -2552,17 +2903,18 @@ static void list_fn(file_info *finfo, const char *name) /* test directory listing speed */ -static void run_dirtest(int dummy) +static BOOL run_dirtest(int dummy) { int i; static struct cli_state cli; int fnum; double t1; + BOOL correct = True; printf("starting directory test\n"); if (!open_connection(&cli)) { - return; + return False; } cli_sockopt(&cli, sockops); @@ -2574,16 +2926,16 @@ static void run_dirtest(int dummy) fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { fprintf(stderr,"Failed to open %s\n", fname); - return; + return False; } cli_close(&cli, fnum); } t1 = end_timer(); - printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn)); - printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn)); - printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn)); + printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL)); + printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL)); + printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL)); printf("dirtest core %g seconds\n", end_timer() - t1); @@ -2594,31 +2946,43 @@ static void run_dirtest(int dummy) cli_unlink(&cli, fname); } - close_connection(&cli); + if (!close_connection(&cli)) { + correct = False; + } printf("finished dirtest\n"); + + return correct; } -static double create_procs(void (*fn)(int)) +static double create_procs(BOOL (*fn)(int), BOOL *result) { int i, status; - volatile int *child_status; + volatile pid_t *child_status; + volatile BOOL *child_status_out; int synccount; int tries = 8; - start_timer(); - synccount = 0; - child_status = (volatile int *)shm_setup(sizeof(int)*nprocs); + child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs); if (!child_status) { printf("Failed to setup shared memory\n"); - return end_timer(); + return -1; } - memset((char *)child_status, 0, sizeof(int)*nprocs); + child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs); + if (!child_status_out) { + printf("Failed to setup result status shared memory\n"); + return -1; + } + + memset(child_status, 0, sizeof(pid_t)*nprocs); + memset(child_status_out, True, sizeof(BOOL)*nprocs); + + start_timer(); for (i=0;i<nprocs;i++) { procnum = i; @@ -2635,14 +2999,14 @@ static double create_procs(void (*fn)(int)) printf("pid %d failed to start\n", (int)getpid()); _exit(1); } - msleep(10); + msleep(10); } child_status[i] = getpid(); while (child_status[i]) msleep(2); - fn(i); + child_status_out[i] = fn(i); _exit(0); } } @@ -2658,6 +3022,7 @@ static double create_procs(void (*fn)(int)) if (synccount != nprocs) { printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount); + *result = False; return end_timer(); } @@ -2674,7 +3039,14 @@ static double create_procs(void (*fn)(int)) waitpid(0, &status, 0); printf("*"); } + printf("\n"); + + for (i=0;i<nprocs;i++) { + if (!child_status_out[i]) { + *result = False; + } + } return end_timer(); } @@ -2683,7 +3055,7 @@ static double create_procs(void (*fn)(int)) static struct { char *name; - void (*fn)(int); + BOOL (*fn)(int); unsigned flags; } torture_ops[] = { {"FDPASS", run_fdpasstest, 0}, @@ -2710,8 +3082,10 @@ static struct { {"TCON", run_tcon_test, 0}, {"RW1", run_readwritetest, 0}, {"RW2", run_readwritemulti, FLAG_MULTIPROC}, + {"RW3", run_readwritelarge, 0}, {"OPEN", run_opentest, 0}, {"DELETE", run_deletetest, 0}, + {"W2K", run_w2ktest, 0}, {NULL, NULL, 0}}; @@ -2719,9 +3093,12 @@ static struct { /**************************************************************************** run a specified test or "ALL" ****************************************************************************/ -static void run_test(char *name) +static BOOL run_test(char *name) { + BOOL ret = True; + BOOL result = True; int i; + double t; if (strequal(name,"ALL")) { for (i=0;torture_ops[i].name;i++) { run_test(torture_ops[i].name); @@ -2729,20 +3106,30 @@ static void run_test(char *name) } for (i=0;torture_ops[i].name;i++) { - fstrcpy(randomfname, "\\XXXXXXX"); - mktemp(randomfname); + snprintf(randomfname, sizeof(randomfname), "\\XX%x", + (unsigned)random()); if (strequal(name, torture_ops[i].name)) { - start_timer(); printf("Running %s\n", name); if (torture_ops[i].flags & FLAG_MULTIPROC) { - create_procs(torture_ops[i].fn); + t = create_procs(torture_ops[i].fn, &result); + if (!result) { + ret = False; + printf("TEST %s FAILED!\n", name); + } + } else { - torture_ops[i].fn(0); + start_timer(); + if (!torture_ops[i].fn(0)) { + ret = False; + printf("TEST %s FAILED!\n", name); + } + t = end_timer(); } - printf("%s took %g secs\n\n", name, end_timer()); + printf("%s took %g secs\n\n", name, t); } } + return ret; } @@ -2790,13 +3177,19 @@ static void usage(void) extern int optind; extern FILE *dbf; static pstring servicesf = CONFIGFILE; + BOOL correct = True; dbf = stdout; +#ifdef HAVE_SETBUFFER setbuffer(stdout, NULL, 0); - +#endif charset_initialise(); - + + codepage_initialise(lp_client_code_page()); + + codepage_initialise(lp_client_code_page()); + lp_load(servicesf,True,False,False); load_interfaces(); @@ -2886,12 +3279,18 @@ static void usage(void) host, share, username, myname); if (argc == 1) { - run_test("ALL"); + correct = run_test("ALL"); } else { for (i=1;i<argc;i++) { - run_test(argv[i]); + if (!run_test(argv[i])) { + correct = False; + } } } - return(0); + if (correct) { + return(0); + } else { + return(1); + } } diff --git a/source/web/statuspage.c b/source/web/statuspage.c index 27a40d16958..f3b07425b78 100644 --- a/source/web/statuspage.c +++ b/source/web/statuspage.c @@ -1,6 +1,6 @@ /* Unix SMB/Netbios implementation. - Version 1.9. + Version 2.2. web status page Copyright (C) Andrew Tridgell 1997-1998 @@ -76,6 +76,10 @@ static void print_share_mode(share_mode_entry *e, char *fname) static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state) { struct connections_data crec; + + if (dbuf.dsize != sizeof(crec)) + return 0; + memcpy(&crec, dbuf.dptr, sizeof(crec)); if (crec.cnum == -1 && process_exists(crec.pid)) { @@ -92,10 +96,14 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state) { struct connections_data crec; + + if (dbuf.dsize != sizeof(crec)) + return 0; + memcpy(&crec, dbuf.dptr, sizeof(crec)); - if (crec.cnum != -1 || !process_exists(crec.pid) || - (crec.pid == smbd_pid)) return 0; + if (crec.cnum != -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid)) + return 0; printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n", (int)crec.pid, @@ -114,9 +122,14 @@ static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st static int traverse_fn3(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state) { struct connections_data crec; + + if (dbuf.dsize != sizeof(crec)) + return 0; + memcpy(&crec, dbuf.dptr, sizeof(crec)); - if (crec.cnum == -1 || !process_exists(crec.pid)) return 0; + if (crec.cnum == -1 || !process_exists(crec.pid)) + return 0; printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n", crec.name,uidtoname(crec.uid), @@ -174,7 +187,7 @@ void status_page(void) refresh_interval = atoi(v); } - tdb = tdb_open(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0); + tdb = tdb_open_log(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0); if (tdb) tdb_traverse(tdb, traverse_fn1, NULL); printf("<H2>Server Status</H2>\n"); @@ -278,4 +291,3 @@ void status_page(void) printf("//-->\n</script>\n"); } } - diff --git a/source/web/swat.c b/source/web/swat.c index 54b8b27a6dd..2a141e9898e 100644 --- a/source/web/swat.c +++ b/source/web/swat.c @@ -344,6 +344,7 @@ static void write_config(FILE *f, BOOL show_defaults, char *(*dos_to_ext)(char * static int save_reload(int snum) { FILE *f; + struct stat st; f = sys_fopen(servicesf,"w"); if (!f) { @@ -351,6 +352,12 @@ static int save_reload(int snum) return 0; } + /* just in case they have used the buggy xinetd to create the file */ + if (fstat(fileno(f), &st) == 0 && + (st.st_mode & S_IWOTH)) { + fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); + } + write_config(f, False, _dos_to_unix); if (snum) lp_dump_one(f, False, snum, _dos_to_unix); @@ -419,7 +426,7 @@ static void commit_parameters(int snum) ****************************************************************************/ static void image_link(char *name,char *hlink, char *src) { - printf("<A HREF=\"%s/%s\"><img src=\"/swat/%s\" alt=\"%s\"></A>\n", + printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n", cgi_baseurl(), hlink, src, name); } @@ -984,6 +991,7 @@ static void printers_page(void) char *page; fault_setup(NULL); + umask(S_IWGRP | S_IWOTH); #if defined(HAVE_SET_AUTH_PARAMETERS) set_auth_parameters(argc, argv); |