diff options
Diffstat (limited to 'source')
48 files changed, 800 insertions, 245 deletions
diff --git a/source/aclocal.m4 b/source/aclocal.m4 index 59bd26bd245..af7ed7b4068 100644 --- a/source/aclocal.m4 +++ b/source/aclocal.m4 @@ -804,7 +804,7 @@ AC_DEFUN( [AC_TRY_RUN_STRICT], old_LDFLAGS="$LDFLAGS"; LDFLAGS="$4"; export LDFLAGS; - AC_TRY_RUN([$1],[$5],[$6],[$7]); + AC_TRY_RUN([$1],[$5],[$6],[$7]) CFLAGS="$old_CFLAGS"; old_CFLAGS=""; export CFLAGS; @@ -892,6 +892,8 @@ AC_DEFUN([SMB_CHECK_DMAPI], LIBS="$LIBS $samba_dmapi_libs" AC_TRY_LINK( [ +#include <time.h> /* needed by Tru64 */ +#include <sys/types.h> /* needed by AIX */ #ifdef HAVE_XFS_DMAPI_H #include <xfs/dmapi.h> #elif defined(HAVE_SYS_DMI_H) @@ -906,14 +908,12 @@ AC_DEFUN([SMB_CHECK_DMAPI], /* This link test is designed to fail on IRI 6.4, but should * succeed on Linux, IRIX 6.5 and AIX. */ -void main(void) { char * version; dm_eventset_t events; /* This doesn't take an argument on IRIX 6.4. */ dm_init_service(&version); /* IRIX 6.4 expects events to be a pointer. */ DMEV_ISSET(DM_EVENT_READ, events); -} ], [ true # DMAPI link test succeeded diff --git a/source/client/client.c b/source/client/client.c index 94fcaaca00d..0a695436f57 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -447,7 +447,14 @@ static void adjust_do_list_queue(void) * If the starting point of the queue is more than half way through, * move everything toward the beginning. */ - if (do_list_queue && (do_list_queue_start == do_list_queue_end)) { + + if (do_list_queue == NULL) { + DEBUG(4,("do_list_queue is empty\n")); + do_list_queue_start = do_list_queue_end = 0; + return; + } + + if (do_list_queue_start == do_list_queue_end) { DEBUG(4,("do_list_queue is empty\n")); do_list_queue_start = do_list_queue_end = 0; *do_list_queue = '\0'; @@ -3422,8 +3429,9 @@ static int do_message_op(void) /* set default debug level to 0 regardless of what smb.conf sets */ setup_logging( "smbclient", True ); DEBUGLEVEL_CLASS[DBGC_ALL] = 1; - dbf = x_stderr; - x_setbuf( x_stderr, NULL ); + if ((dbf = x_fdup(x_stderr))) { + x_setbuf( dbf, NULL ); + } pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); diff --git a/source/client/smbctool.c b/source/client/smbctool.c index 5b21d195b76..3233ee49554 100644 --- a/source/client/smbctool.c +++ b/source/client/smbctool.c @@ -528,7 +528,14 @@ static void adjust_do_list_queue(void) * If the starting point of the queue is more than half way through, * move everything toward the beginning. */ - if (do_list_queue && (do_list_queue_start == do_list_queue_end)) { + + if (do_list_queue == NULL) { + DEBUG(4,("do_list_queue is empty\n")); + do_list_queue_start = do_list_queue_end = 0; + return; + } + + if (do_list_queue_start == do_list_queue_end) { DEBUG(4,("do_list_queue is empty\n")); do_list_queue_start = do_list_queue_end = 0; *do_list_queue = '\0'; @@ -3561,10 +3568,11 @@ static int do_message_op(void) set_global_myname( "" ); /* set default debug level to 0 regardless of what smb.conf sets */ - setup_logging( "smbclient", True ); + setup_logging( "smbctool", True ); DEBUGLEVEL_CLASS[DBGC_ALL] = 1; - dbf = x_stderr; - x_setbuf( x_stderr, NULL ); + if ((dbf = x_fdup(x_stderr))) { + x_setbuf( dbf, NULL ); + } pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); diff --git a/source/configure.in b/source/configure.in index 799441ed950..9dce9e0e2c9 100644 --- a/source/configure.in +++ b/source/configure.in @@ -1719,6 +1719,9 @@ if test "$enable_shared" = "yes"; then LDSHFLAGS="-Wl,-G,-bexpall" DYNEXP="-Wl,-brtl,-bexpall,-bbigtoc" PICFLAGS="-O2" + # as AIX code is always position independent... + # .po will just create compile warnings, use .o: + PICSUFFIX="o" if test "${GCC}" != "yes"; then ## for funky AIX compiler using strncpy() CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" @@ -1848,6 +1851,9 @@ main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }] samba_cv_have_longlong=yes,samba_cv_have_longlong=no,samba_cv_have_longlong=cross)]) if test x"$samba_cv_have_longlong" = x"yes"; then AC_DEFINE(HAVE_LONGLONG,1,[Whether the host supports long long's]) + AC_CHECK_TYPE(intptr_t, unsigned long long) +else + AC_CHECK_TYPE(intptr_t, unsigned long) fi # @@ -3457,6 +3463,7 @@ if test x"$with_ads_support" != x"no"; then AC_CHECK_FUNC_EXT(krb5_get_init_creds_opt_set_pac_request, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_renewed_creds, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_kdc_cred, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_free_error_contents, $KRB5_LIBS) LIBS="$KRB5_LIBS $LIBS" @@ -3506,6 +3513,18 @@ if test x"$with_ads_support" != x"no"; then [Whether the krb5_ap_req struct has a ticket pointer]) fi + AC_CACHE_CHECK([for e_data pointer in krb5_error], + samba_cv_HAVE_E_DATA_POINTER_IN_KRB5_ERROR,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_error err; err.e_data = NULL;], + samba_cv_HAVE_E_DATA_POINTER_IN_KRB5_ERROR=yes, + samba_cv_HAVE_E_DATA_POINTER_IN_KRB5_ERROR=no)]) + + if test x"$samba_cv_HAVE_E_DATA_POINTER_IN_KRB5_ERROR" = x"yes"; then + AC_DEFINE(HAVE_E_DATA_POINTER_IN_KRB5_ERROR,1, + [Whether the krb5_error struct has a e_data pointer]) + fi + AC_CACHE_CHECK([for krb5_crypto type], samba_cv_HAVE_KRB5_CRYPTO,[ AC_TRY_COMPILE([#include <krb5.h>], diff --git a/source/include/ads.h b/source/include/ads.h index 210c6c80f17..74a29e4f795 100644 --- a/source/include/ads.h +++ b/source/include/ads.h @@ -279,6 +279,10 @@ typedef void **ADS_MODLIST; #define KRB5_ADDR_NETBIOS 0x14 #endif +#ifndef KRB5KRB_ERR_RESPONSE_TOO_BIG +#define KRB5KRB_ERR_RESPONSE_TOO_BIG (-1765328332L) +#endif + #ifdef HAVE_KRB5 typedef struct { #if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ diff --git a/source/include/includes.h b/source/include/includes.h index e6358f5abb4..59e8e5cd0fb 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -1540,6 +1540,9 @@ krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr krb5_error_code smb_krb5_free_addresses(krb5_context context, smb_krb5_addresses *addr); NTSTATUS krb5_to_nt_status(krb5_error_code kerberos_error); krb5_error_code nt_status_to_krb5(NTSTATUS nt_status); +void smb_krb5_free_error(krb5_context context, krb5_error *krberror); +krb5_error_code handle_krberror_packet(krb5_context context, + krb5_data *packet); #endif /* HAVE_KRB5 */ diff --git a/source/lib/gencache.c b/source/lib/gencache.c index 6725ed4c120..561a019429a 100644 --- a/source/lib/gencache.c +++ b/source/lib/gencache.c @@ -28,6 +28,7 @@ #define TIMEOUT_LEN 12 #define CACHE_DATA_FMT "%12u/%s" +#define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us" static TDB_CONTEXT *cache; @@ -242,8 +243,9 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) /* fail completely if get null pointers passed */ SMB_ASSERT(keystr); - if (!gencache_init()) + if (!gencache_init()) { return False; + } keybuf.dptr = SMB_STRDUP(keystr); keybuf.dsize = strlen(keystr)+1; @@ -256,13 +258,26 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) time_t t; unsigned u; int status; + char *fmt; + + v = SMB_MALLOC(databuf.dsize + 1 - TIMEOUT_LEN); + if (!v) { + return False; + } - v = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN); - SAFE_FREE(databuf.dptr); - status = sscanf(entry_buf, CACHE_DATA_FMT, &u, v); + + asprintf(&fmt, READ_CACHE_DATA_FMT_TEMPLATE, (unsigned int)databuf.dsize - TIMEOUT_LEN); + if (!fmt) { + SAFE_FREE(v); + return False; + } + + status = sscanf(entry_buf, fmt, &u, v); + SAFE_FREE(fmt); + if ( status != 2 ) { - DEBUG(0, ("gencache_get: Invalid return %d from sscanf\n", status )); + DEBUG(0, ("gencache_get: Invalid return %d from sscanf\n", status )); } t = u; SAFE_FREE(entry_buf); @@ -271,13 +286,15 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) "timeout = %s", t > time(NULL) ? "valid" : "expired", keystr, v, ctime(&t))); - if (valstr) + if (valstr) { *valstr = v; - else + } else { SAFE_FREE(v); + } - if (timeout) + if (timeout) { *timeout = t; + } return t > time(NULL); @@ -285,17 +302,17 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) SAFE_FREE(databuf.dptr); - if (valstr) + if (valstr) { *valstr = NULL; - if (timeout) + } + if (timeout) { timeout = NULL; + } DEBUG(10, ("Cache entry with key = %s couldn't be found\n", keystr)); - return False; } - /** * Iterate through all entries which key matches to specified pattern * @@ -327,8 +344,13 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time first_node = node; while (node) { + char *fmt; + /* ensure null termination of the key string */ keystr = SMB_STRNDUP(node->node_key.dptr, node->node_key.dsize); + if (!keystr) { + break; + } /* * We don't use gencache_get function, because we need to iterate through @@ -342,11 +364,33 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time continue; } entry = SMB_STRNDUP(databuf.dptr, databuf.dsize); + if (!entry) { + SAFE_FREE(databuf.dptr); + SAFE_FREE(keystr); + break; + } + SAFE_FREE(databuf.dptr); - valstr = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN); - status = sscanf(entry, CACHE_DATA_FMT, &u, valstr); + + valstr = SMB_MALLOC(databuf.dsize + 1 - TIMEOUT_LEN); + if (!valstr) { + SAFE_FREE(entry); + SAFE_FREE(keystr); + break; + } + + asprintf(&fmt, READ_CACHE_DATA_FMT_TEMPLATE, (unsigned int)databuf.dsize - TIMEOUT_LEN); + if (!fmt) { + SAFE_FREE(valstr); + SAFE_FREE(entry); + SAFE_FREE(keystr); + break; + } + status = sscanf(entry, fmt, &u, valstr); + SAFE_FREE(fmt); + if ( status != 2 ) { - DEBUG(0,("gencache_iterate: invalid return from sscanf %d\n",status)); + DEBUG(0,("gencache_iterate: invalid return from sscanf %d\n",status)); } timeout = u; diff --git a/source/lib/getsmbpass.c b/source/lib/getsmbpass.c index a7780f7c12b..bebddc69eb4 100644 --- a/source/lib/getsmbpass.c +++ b/source/lib/getsmbpass.c @@ -163,7 +163,7 @@ char *getsmbpass(const char *prompt) fprintf(out, "\n"); fflush(out); - if (in != stdin) /* We opened the terminal; now close it. */ + if (in && in != stdin) /* We opened the terminal; now close it. */ fclose(in); /* Catch problematic signals */ diff --git a/source/lib/readline.c b/source/lib/readline.c index c1f1dc7f400..1f599dc0a7f 100644 --- a/source/lib/readline.c +++ b/source/lib/readline.c @@ -59,8 +59,11 @@ static char *smb_readline_replacement(const char *prompt, void (*callback)(void) int fd = x_fileno(x_stdin); char *ret; - x_fprintf(dbf, "%s", prompt); - x_fflush(dbf); + /* Prompt might be NULL in non-interactive mode. */ + if (prompt) { + x_fprintf(x_stdout, "%s", prompt); + x_fflush(x_stdout); + } while (1) { timeout.tv_sec = 5; @@ -85,34 +88,42 @@ static char *smb_readline_replacement(const char *prompt, void (*callback)(void) char *smb_readline(const char *prompt, void (*callback)(void), char **(completion_fn)(const char *text, int start, int end)) { + char *ret; + BOOL interactive; + + interactive = isatty(x_fileno(x_stdin)) || getenv("CLI_FORCE_INTERACTIVE"); + if (!interactive) { + return smb_readline_replacement(NULL, callback, completion_fn); + } + #if HAVE_LIBREADLINE - if (isatty(x_fileno(x_stdin))) { - char *ret; - - /* Aargh! Readline does bizzare things with the terminal width - that mucks up expect(1). Set CLI_NO_READLINE in the environment - to force readline not to be used. */ - - if (getenv("CLI_NO_READLINE")) - return smb_readline_replacement(prompt, callback, completion_fn); - - if (completion_fn) { - /* The callback prototype has changed slightly between - different versions of Readline, so the same function - works in all of them to date, but we get compiler - warnings in some. */ - rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn; - } - if (callback) - rl_event_hook = (Function *)callback; - ret = readline(prompt); - if (ret && *ret) - add_history(ret); - return ret; - } else + /* Aargh! Readline does bizzare things with the terminal width + that mucks up expect(1). Set CLI_NO_READLINE in the environment + to force readline not to be used. */ + + if (getenv("CLI_NO_READLINE")) + return smb_readline_replacement(prompt, callback, completion_fn); + + if (completion_fn) { + /* The callback prototype has changed slightly between + different versions of Readline, so the same function + works in all of them to date, but we get compiler + warnings in some. */ + rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn; + } + + if (callback) + rl_event_hook = (Function *)callback; + ret = readline(prompt); + if (ret && *ret) + add_history(ret); + +#else + ret = smb_readline_replacement(prompt, callback, completion_fn); #endif - return smb_readline_replacement(prompt, callback, completion_fn); + + return ret; } /**************************************************************************** diff --git a/source/lib/xfile.c b/source/lib/xfile.c index 71f8bdbcbb6..ef33c7894f7 100644 --- a/source/lib/xfile.c +++ b/source/lib/xfile.c @@ -123,6 +123,28 @@ XFILE *x_fopen(const char *fname, int flags, mode_t mode) return ret; } +XFILE *x_fdup(const XFILE *f) +{ + XFILE *ret; + int fd; + + fd = dup(x_fileno(f)); + if (fd < 0) { + return NULL; + } + + ret = SMB_CALLOC_ARRAY(XFILE, 1); + if (!ret) { + close(fd); + return NULL; + } + + ret->fd = fd; + ret->open_flags = f->open_flags; + x_setvbuf(ret, NULL, X_IOFBF, XBUFSIZE); + return ret; +} + /* simulate fclose() */ int x_fclose(XFILE *f) { @@ -220,7 +242,7 @@ size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) } /* at least fileno() is simple! */ -int x_fileno(XFILE *f) +int x_fileno(const XFILE *f) { return f->fd; } diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c index 2dfdc31dd56..90650e1dce0 100644 --- a/source/libads/kerberos.c +++ b/source/libads/kerberos.c @@ -195,6 +195,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } if (!ads->auth.password) { + SAFE_FREE(s); return KRB5_LIBOS_CANTREADPWD; } @@ -205,7 +206,7 @@ int ads_kinit_password(ADS_STRUCT *ads) DEBUG(0,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); } - free(s); + SAFE_FREE(s); return ret; } diff --git a/source/libads/krb5_setpw.c b/source/libads/krb5_setpw.c index ec2ff5afb1a..07e6320c266 100644 --- a/source/libads/krb5_setpw.c +++ b/source/libads/krb5_setpw.c @@ -45,6 +45,14 @@ #define KRB5_KPASSWD_BAD_PRINCIPAL 9 #define KRB5_KPASSWD_ETYPE_NOSUPP 10 +/* + * we've got to be able to distinguish KRB_ERRORs from other + * requests - valid response for CHPW v2 replies. + */ + +#define krb5_is_krb_error(packet) \ + ( packet && packet->length && (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e)) + /* This implements kerberos password change protocol as specified in * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt * as well as microsoft version of the protocol @@ -129,14 +137,16 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, krb5_data *ap_req, const char *princ, const char *passwd, + BOOL use_tcp, krb5_data *packet) { krb5_error_code ret; krb5_data cipherpw; krb5_data encoded_setpw; krb5_replay_data replay; - char *p; + char *p, *msg_start; DATA_BLOB setpw; + unsigned int msg_length; ret = krb5_auth_con_setflags(context, auth_context,KRB5_AUTH_CONTEXT_DO_SEQUENCE); @@ -172,12 +182,16 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return ret; } - packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + 6); + packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + (use_tcp ? 10 : 6 )); if (!packet->data) return -1; + + /* see the RFC for details */ - p = ((char *)packet->data) + 2; + + msg_start = p = ((char *)packet->data) + (use_tcp ? 4 : 0); + p += 2; RSSVAL(p, 0, pversion); p += 2; RSSVAL(p, 0, ap_req->length); @@ -187,7 +201,12 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; packet->length = PTR_DIFF(p,packet->data); - RSSVAL(packet->data, 0, packet->length); + msg_length = PTR_DIFF(p,msg_start); + + if (use_tcp) { + RSIVAL(packet->data, 0, msg_length); + } + RSSVAL(msg_start, 0, msg_length); free(cipherpw.data); /* from 'krb5_mk_priv(...)' */ @@ -248,7 +267,8 @@ static krb5_error_code setpw_result_code_string(krb5_context context, return KRB5KRB_ERR_GENERIC; } } -static krb5_error_code parse_setpw_reply(krb5_context context, +static krb5_error_code parse_setpw_reply(krb5_context context, + BOOL use_tcp, krb5_auth_context auth_context, krb5_data *packet) { @@ -259,23 +279,41 @@ static krb5_error_code parse_setpw_reply(krb5_context context, krb5_data clearresult; krb5_ap_rep_enc_part *ap_rep_enc; krb5_replay_data replay; - - if (packet->length < 4) { + unsigned int msg_length = packet->length; + + + if (packet->length < (use_tcp ? 8 : 4)) { return KRB5KRB_AP_ERR_MODIFIED; } p = packet->data; + /* + ** see if it is an error + */ + if (krb5_is_krb_error(packet)) { + + ret = handle_krberror_packet(context, packet); + if (ret) { + return ret; + } + } + - if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) { - /* it's an error packet. We should parse it ... */ - DEBUG(1,("Got error packet 0x%x from kpasswd server\n", - ((char *)packet->data)[0])); - return KRB5KRB_AP_ERR_MODIFIED; + /* tcp... */ + if (use_tcp) { + msg_length -= 4; + if (RIVAL(p, 0) != msg_length) { + DEBUG(1,("Bad TCP packet length (%d/%d) from kpasswd server\n", + RIVAL(p, 0), msg_length)); + return KRB5KRB_AP_ERR_MODIFIED; + } + + p += 4; } - if (RSVAL(p, 0) != packet->length) { + if (RSVAL(p, 0) != msg_length) { DEBUG(1,("Bad packet length (%d/%d) from kpasswd server\n", - RSVAL(p, 0), packet->length)); + RSVAL(p, 0), msg_length)); return KRB5KRB_AP_ERR_MODIFIED; } @@ -342,9 +380,9 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return KRB5KRB_AP_ERR_MODIFIED; } - if(res_code == KRB5_KPASSWD_SUCCESS) - return 0; - else { + if (res_code == KRB5_KPASSWD_SUCCESS) { + return 0; + } else { const char *errstr; setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s (%d)\n", errstr, res_code)); @@ -365,7 +403,10 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, int ret, sock; socklen_t addr_len; struct sockaddr remote_addr, local_addr; + struct in_addr *addr = interpret_addr2(kdc_host); krb5_address local_kaddr, remote_kaddr; + BOOL use_tcp = False; + ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); @@ -373,102 +414,123 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - - sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); - if (sock == -1) { - int rc = errno; - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", - kdc_host, strerror(errno))); - return ADS_ERROR_SYSTEM(rc); - } - - addr_len = sizeof(remote_addr); - getpeername(sock, &remote_addr, &addr_len); - addr_len = sizeof(local_addr); - getsockname(sock, &local_addr, &addr_len); - - setup_kaddr(&remote_kaddr, &remote_addr); - setup_kaddr(&local_kaddr, &local_addr); - - ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); - if (ret) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, - princ, newpw, &chpw_req); - if (ret) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { - close(sock); - free(chpw_req.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - return ADS_ERROR_SYSTEM(errno); - } + do { - free(chpw_req.data); + if (!use_tcp) { - chpw_rep.length = 1500; - chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); - if (!chpw_rep.data) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - errno = ENOMEM; - return ADS_ERROR_SYSTEM(errno); - } + sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); - ret = read(sock, chpw_rep.data, chpw_rep.length); - if (ret < 0) { - close(sock); - free(chpw_rep.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); - return ADS_ERROR_SYSTEM(errno); - } + } else { - close(sock); - chpw_rep.length = ret; + sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT, + LONG_CONNECT_TIMEOUT); + } - ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); - if (ret) { - free(chpw_rep.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } + if (sock == -1) { + int rc = errno; + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", + kdc_host, strerror(errno))); + return ADS_ERROR_SYSTEM(rc); + } + + addr_len = sizeof(remote_addr); + getpeername(sock, &remote_addr, &addr_len); + addr_len = sizeof(local_addr); + getsockname(sock, &local_addr, &addr_len); + + setup_kaddr(&remote_kaddr, &remote_addr); + setup_kaddr(&local_kaddr, &local_addr); + + ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); + if (ret) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, + princ, newpw, use_tcp, &chpw_req); + if (ret) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } - ret = parse_setpw_reply(context, auth_context, &chpw_rep); - free(chpw_rep.data); + ret = write(sock, chpw_req.data, chpw_req.length); - if (ret) { - free(ap_req.data); + if (ret != chpw_req.length) { + close(sock); + SAFE_FREE(chpw_req.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + return ADS_ERROR_SYSTEM(errno); + } + + SAFE_FREE(chpw_req.data); + + chpw_rep.length = 1500; + chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); + if (!chpw_rep.data) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + errno = ENOMEM; + return ADS_ERROR_SYSTEM(errno); + } + + ret = read(sock, chpw_rep.data, chpw_rep.length); + if (ret < 0) { + close(sock); + SAFE_FREE(chpw_rep.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); + return ADS_ERROR_SYSTEM(errno); + } + + close(sock); + chpw_rep.length = ret; + + ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); + if (ret) { + SAFE_FREE(chpw_rep.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = parse_setpw_reply(context, use_tcp, auth_context, &chpw_rep); + SAFE_FREE(chpw_rep.data); + + if (ret) { + + if (ret == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) { + DEBUG(5, ("Trying setpw with TCP!!!\n")); + use_tcp = True; + continue; + } + + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("parse_setpw_reply failed (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + SAFE_FREE(ap_req.data); krb5_auth_con_free(context, auth_context); - DEBUG(1,("parse_setpw_reply failed (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - free(ap_req.data); - krb5_auth_con_free(context, auth_context); + } while ( ret ); return ADS_SUCCESS; } diff --git a/source/libads/ldap.c b/source/libads/ldap.c index 7fb5dac51bb..397d8c02f07 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -904,7 +904,13 @@ char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) **/ char *ads_parent_dn(const char *dn) { - char *p = strchr(dn, ','); + char *p; + + if (dn == NULL) { + return NULL; + } + + p = strchr(dn, ','); if (p == NULL) { return NULL; @@ -1430,16 +1436,28 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { talloc_destroy(ctx); ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + return ADS_ERROR(LDAP_NO_MEMORY); } /* Add the extra principal */ psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); + if (!psp1) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp1); strlower_m(&psp1[strlen(spn)]); DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); servicePrincipalName[0] = psp1; psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm); + if (!psp2) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp2); strlower_m(&psp2[strlen(spn)]); DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); @@ -1449,6 +1467,12 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n * the KDC doesn't send "server principal unknown" errors to clients * which use the DNS name in determining service principal names. */ psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn); + if (!psp3) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp3); strlower_m(&psp3[strlen(spn)]); if (strcmp(psp2, psp3) != 0) { @@ -1956,8 +1980,10 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, return NULL; } - memcpy(&strings[*num_strings], new_strings, - sizeof(*new_strings) * num_new_strings); + if (new_strings && num_new_strings) { + memcpy(&strings[*num_strings], new_strings, + sizeof(*new_strings) * num_new_strings); + } (*num_strings) += num_new_strings; diff --git a/source/libads/ldap_printer.c b/source/libads/ldap_printer.c index d6ac09d22bd..12bf6eec1df 100644 --- a/source/libads/ldap_printer.c +++ b/source/libads/ldap_printer.c @@ -119,6 +119,9 @@ static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (value->type != REG_DWORD) return False; str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p)); + if (!str_value) { + return False; + } status = ads_mod_str(ctx, mods, value->valuename, str_value); return ADS_ERR_OK(status); } @@ -136,6 +139,9 @@ static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, return False; str_value = talloc_asprintf(ctx, "%s", *(value->data_p) ? "TRUE" : "FALSE"); + if (!str_value) { + return False; + } status = ads_mod_str(ctx, mods, value->valuename, str_value); return ADS_ERR_OK(status); } @@ -162,6 +168,9 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (num_vals) { str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1); + if (!str_values) { + return False; + } memset(str_values, '\0', (num_vals + 1) * sizeof(char *)); diff --git a/source/libsmb/asn1.c b/source/libsmb/asn1.c index 8c986c9588f..544ee78d406 100644 --- a/source/libsmb/asn1.c +++ b/source/libsmb/asn1.c @@ -393,20 +393,30 @@ BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) { int len; - if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; + char *str; + + *s = NULL; + + if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) { + return False; + } len = asn1_tag_remaining(data); if (len < 0) { data->has_error = True; return False; } - *s = SMB_MALLOC(len+1); - if (! *s) { + str = SMB_MALLOC(len+1); + if (!str) { data->has_error = True; return False; } - asn1_read(data, *s, len); - (*s)[len] = 0; + asn1_read(data, str, len); + str[len] = 0; asn1_end_tag(data); + + if (!data->has_error) { + *s = str; + } return !data->has_error; } diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index e0d6b09d977..abb3843bacb 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -1310,7 +1310,64 @@ done: return ret; } - + + void smb_krb5_free_error(krb5_context context, krb5_error *krberror) +{ +#ifdef HAVE_KRB5_FREE_ERROR_CONTENTS /* Heimdal */ + krb5_free_error_contents(context, krberror); +#else /* MIT */ + krb5_free_error(context, krberror); +#endif +} + + krb5_error_code handle_krberror_packet(krb5_context context, + krb5_data *packet) +{ + krb5_error_code ret; + BOOL got_error_code = False; + + DEBUG(10,("handle_krberror_packet: got error packet\n")); + +#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR /* Heimdal */ + { + krb5_error krberror; + + if ((ret = krb5_rd_error(context, packet, &krberror))) { + DEBUG(10,("handle_krberror_packet: krb5_rd_error failed with: %s\n", + error_message(ret))); + return ret; + } + + if (krberror.e_data == NULL || krberror.e_data->data == NULL) { + ret = (krb5_error_code) krberror.error_code; + got_error_code = True; + } + + smb_krb5_free_error(context, &krberror); + } +#else /* MIT */ + { + krb5_error *krberror; + + if ((ret = krb5_rd_error(context, packet, &krberror))) { + DEBUG(10,("handle_krberror_packet: krb5_rd_error failed with: %s\n", + error_message(ret))); + return ret; + } + + if (krberror->e_data.data == NULL) { + ret = ERROR_TABLE_BASE_krb5 + (krb5_error_code) krberror->error; + got_error_code = True; + } + smb_krb5_free_error(context, krberror); + } +#endif + if (got_error_code) { + DEBUG(5,("handle_krberror_packet: got KERBERR from kpasswd: %s (%d)\n", + error_message(ret), ret)); + } + return ret; +} #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c index e87e9f0c7c9..3dad37d9e1b 100644 --- a/source/libsmb/clispnego.c +++ b/source/libsmb/clispnego.c @@ -163,11 +163,18 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_end_tag(&data); ret = !data.has_error; + if (data.has_error) { + int j; + SAFE_FREE(principal); + for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { + SAFE_FREE(OIDs[j]); + } + } + asn1_free(&data); return ret; } - /* generate a negTokenTarg packet given a list of OIDs and a security blob */ @@ -212,7 +219,6 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) return ret; } - /* parse a negTokenTarg packet giving a list of OIDs and a security blob */ @@ -248,6 +254,11 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_end_tag(&data); if (data.has_error) { + int j; + data_blob_free(secblob); + for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { + SAFE_FREE(OIDs[j]); + } DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data.ofs)); asn1_free(&data); return False; @@ -313,6 +324,10 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) ret = !data.has_error; + if (data.has_error) { + data_blob_free(ticket); + } + asn1_free(&data); return ret; @@ -390,6 +405,12 @@ BOOL spnego_parse_challenge(const DATA_BLOB blob, asn1_end_tag(&data); ret = !data.has_error; + + if (data.has_error) { + data_blob_free(chal1); + data_blob_free(chal2); + } + asn1_free(&data); return ret; } @@ -438,6 +459,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) if (data.has_error) { DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data.ofs)); + data_blob_free(auth); asn1_free(&data); return False; } @@ -537,4 +559,3 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_free(&data); return True; } - diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index 2436cc9136f..4ea0ab6eb63 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/libsmb/libsmbclient.c @@ -6036,7 +6036,11 @@ smbc_option_get(SMBCCTX *context, /* * Log to standard error instead of standard output. */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->internal->_debug_stderr; +#else return (void *) context->internal->_debug_stderr; +#endif } else if (strcmp(option_name, "auth_function") == 0) { /* * Use the new-style authentication function which includes diff --git a/source/locking/locking.c b/source/locking/locking.c index b536844319a..0ffb9374326 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -846,7 +846,7 @@ BOOL rename_share_filename(struct share_mode_lock *lck, SDEV_T_VAL(frm,0,lck->dev); SINO_T_VAL(frm,8,lck->ino); - DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len )); + DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); safe_strcpy(&frm[16], lck->servicepath, sp_len); safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len); diff --git a/source/locking/posix.c b/source/locking/posix.c index e7075c57a64..4a5f59b622d 100644 --- a/source/locking/posix.c +++ b/source/locking/posix.c @@ -454,9 +454,8 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T entry->start == start && entry->size == size) { - /* Make a copy if requested. */ - if (pl) - *pl = *entry; + /* Make a copy */ + *pl = *entry; /* Found it - delete it. */ if (count == 1) { diff --git a/source/nmbd/nmbd_subnetdb.c b/source/nmbd/nmbd_subnetdb.c index 5a93d8bec03..3b9be2c2ce9 100644 --- a/source/nmbd/nmbd_subnetdb.c +++ b/source/nmbd/nmbd_subnetdb.c @@ -57,8 +57,6 @@ yet and it may be in use by a response record void close_subnet(struct subnet_record *subrec) { - DLIST_REMOVE(subnetlist, subrec); - if (subrec->dgram_sock != -1) { close(subrec->dgram_sock); subrec->dgram_sock = -1; @@ -67,6 +65,8 @@ void close_subnet(struct subnet_record *subrec) close(subrec->nmb_sock); subrec->nmb_sock = -1; } + + DLIST_REMOVE(subnetlist, subrec); } /**************************************************************************** diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c index a8eb6f86d0d..3ed651f8cdc 100644 --- a/source/nsswitch/winbindd_ads.c +++ b/source/nsswitch/winbindd_ads.c @@ -806,7 +806,8 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, status = lookup_usergroups_memberof(domain, mem_ctx, user_dn, &primary_group, - p_num_groups, user_sids); + &num_groups, user_sids); + *p_num_groups = (uint32)num_groups; if (NT_STATUS_IS_OK(status)) { goto done; } @@ -816,7 +817,8 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, status = lookup_usergroups_member(domain, mem_ctx, user_dn, &primary_group, - p_num_groups, user_sids); + &num_groups, user_sids); + *p_num_groups = (uint32)num_groups; goto done; } diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c index 86846f7835c..ba69d41392e 100644 --- a/source/nsswitch/winbindd_cache.c +++ b/source/nsswitch/winbindd_cache.c @@ -229,8 +229,8 @@ static time_t centry_time(struct cache_entry *centry) { time_t ret; if (centry->len - centry->ofs < sizeof(time_t)) { - DEBUG(0,("centry corruption? needed %d bytes, have %d\n", - sizeof(time_t), centry->len - centry->ofs)); + DEBUG(0,("centry corruption? needed %u bytes, have %u\n", + (unsigned int)sizeof(time_t), (unsigned int)(centry->len - centry->ofs))); smb_panic("centry_time"); } ret = IVAL(centry->data, centry->ofs); /* FIXME: correct ? */ diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c index 5caaa7aa3ad..c0da45d8d03 100644 --- a/source/nsswitch/winbindd_group.c +++ b/source/nsswitch/winbindd_group.c @@ -184,8 +184,8 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain, *gr_mem = buf; *gr_mem_len = buf_len; - DEBUG(10, ("num_mem = %d, len = %d, mem = %s\n", *num_gr_mem, - buf_len, *num_gr_mem ? buf : "NULL")); + DEBUG(10, ("num_mem = %u, len = %u, mem = %s\n", (unsigned int)*num_gr_mem, + (unsigned int)buf_len, *num_gr_mem ? buf : "NULL")); result = True; done: @@ -795,8 +795,8 @@ void winbindd_getgrent(struct winbindd_cli_state *state) break; } - DEBUG(10, ("list_len = %d, mem_len = %d\n", - gr_mem_list_len, gr_mem_len)); + DEBUG(10, ("list_len = %d, mem_len = %u\n", + gr_mem_list_len, (unsigned int)gr_mem_len)); memcpy(&gr_mem_list[gr_mem_list_len], gr_mem, gr_mem_len); diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index 79c1eda459c..3fd4e6748ae 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -223,7 +223,10 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_ if (mem_ctx == NULL) return NT_STATUS_NO_MEMORY; - attrs = TALLOC_ARRAY(mem_ctx, const char *, 2); + if ((attrs = TALLOC_ARRAY(mem_ctx, const char *, 2)) == NULL) { + ntstatus = NT_STATUS_NO_MEMORY; + goto done; + } /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */ rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1); @@ -1747,6 +1750,9 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc result = pdb_get_backend_private_data(newpwd, my_methods); if (!result) { attr_list = get_userattr_list(NULL, ldap_state->schema_ver); + if (pdb_get_username(newpwd) == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list ); TALLOC_FREE( attr_list ); if (rc != LDAP_SUCCESS) { @@ -2350,6 +2356,10 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, LDAP_OBJ_POSIXGROUP, LDAP_OBJ_GROUPMAP, sid_string_static(group)); + if (filter == NULL) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } rc = smbldap_search(conn, lp_ldap_group_suffix(), LDAP_SCOPE_SUBTREE, filter, id_attrs, 0, @@ -2525,6 +2535,10 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, *pp_sids = NULL; num_sids = 0; + if (pdb_get_username(user) == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + escape_name = escape_ldap_string_alloc(pdb_get_username(user)); if (escape_name == NULL) return NT_STATUS_NO_MEMORY; @@ -2534,6 +2548,10 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, "(&(objectClass=%s)(uid=%s))", LDAP_OBJ_SAMBASAMACCOUNT, escape_name); + if (filter == NULL) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } rc = smbldap_search(conn, lp_ldap_user_suffix(), LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); @@ -2570,6 +2588,10 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|(memberUid=%s)(gidNumber=%d)))", LDAP_OBJ_POSIXGROUP, escape_name, primary_gid); + if (filter == NULL) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } rc = smbldap_search(conn, lp_ldap_group_suffix(), LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); @@ -3379,6 +3401,10 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, filter = talloc_asprintf(mem_ctx, "%s))", filter); + if (filter == NULL) { + return NT_STATUS_NO_MEMORY; + } + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(), LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); @@ -3868,11 +3894,18 @@ const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...) num += 1; va_end(ap); - result = TALLOC_ARRAY(mem_ctx, const char *, num+1); + if ((result = TALLOC_ARRAY(mem_ctx, const char *, num+1)) == NULL) { + return NULL; + } va_start(ap, mem_ctx); - for (i=0; i<num; i++) - result[i] = talloc_strdup(mem_ctx, va_arg(ap, const char*)); + for (i=0; i<num; i++) { + result[i] = talloc_strdup(result, va_arg(ap, const char*)); + if (result[i] == NULL) { + talloc_free(result); + return NULL; + } + } va_end(ap); result[num] = NULL; @@ -4799,6 +4832,9 @@ static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX * pdb_get_username(sam_acct), LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_SAMBASAMACCOUNT); + if (filter == NULL) { + return NT_STATUS_NO_MEMORY; + } rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5014,6 +5050,9 @@ static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_ sid_string_static(&group_sid), LDAP_OBJ_POSIXGROUP, LDAP_OBJ_GROUPMAP); + if (filter == NULL) { + return NT_STATUS_NO_MEMORY; + } rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5125,6 +5164,9 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, sid_string_static(&member_sid), LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_SAMBASAMACCOUNT); + if (filter == NULL) { + return NT_STATUS_NO_MEMORY; + } /* get the member uid */ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); @@ -5291,6 +5333,9 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, pdb_get_username(sampass), LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_SAMBASAMACCOUNT); + if (filter == NULL) { + return NT_STATUS_NO_MEMORY; + } rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { diff --git a/source/rpc_client/cli_ds.c b/source/rpc_client/cli_ds.c index 9c7ad840629..c01a5519660 100644 --- a/source/rpc_client/cli_ds.c +++ b/source/rpc_client/cli_ds.c @@ -100,6 +100,10 @@ NTSTATUS rpccli_ds_enum_domain_trusts(struct rpc_pipe_client *cli, *num_domains = r.num_domains; *trusts = TALLOC_ARRAY(mem_ctx, struct ds_domain_trust, r.num_domains); + if (*trusts == NULL) { + return NT_STATUS_NO_MEMORY; + } + for ( i=0; i< *num_domains; i++ ) { (*trusts)[i].flags = r.domains.trusts[i].flags; (*trusts)[i].parent_index = r.domains.trusts[i].parent_index; diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c index ac797243edc..deb97724a0e 100644 --- a/source/rpc_client/cli_lsarpc.c +++ b/source/rpc_client/cli_lsarpc.c @@ -1177,6 +1177,12 @@ NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX privileges = TALLOC_ARRAY( mem_ctx, fstring, *count ); names = TALLOC_ARRAY( mem_ctx, char *, *count ); + if ((privileges == NULL) || (names == NULL)) { + TALLOC_FREE(privileges); + TALLOC_FREE(names); + return NT_STATUS_NO_MEMORY; + } + for ( i=0; i<*count; i++ ) { UNISTR4 *uni_string = &r.rights->strings[i]; diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c index 1da7a47ea61..ea8db636423 100644 --- a/source/rpc_client/cli_samr.c +++ b/source/rpc_client/cli_samr.c @@ -1505,6 +1505,12 @@ NTSTATUS rpccli_samr_lookup_rids(struct rpc_pipe_client *cli, *names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1); *name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1); + if ((*names == NULL) || (*name_types == NULL)) { + TALLOC_FREE(*names); + TALLOC_FREE(*name_types); + return NT_STATUS_NO_MEMORY; + } + for (i = 0; i < r.num_names1; i++) { fstring tmp; @@ -1564,6 +1570,12 @@ NTSTATUS rpccli_samr_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1); *rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1); + if ((*rids == NULL) || (*rid_types == NULL)) { + TALLOC_FREE(*rids); + TALLOC_FREE(*rid_types); + return NT_STATUS_NO_MEMORY; + } + for (i = 0; i < r.num_rids1; i++) { (*rids)[i] = r.rids[i]; (*rid_types)[i] = r.types[i]; diff --git a/source/rpc_client/cli_srvsvc.c b/source/rpc_client/cli_srvsvc.c index 2c71d6b18ea..0d50e94d577 100644 --- a/source/rpc_client/cli_srvsvc.c +++ b/source/rpc_client/cli_srvsvc.c @@ -108,6 +108,9 @@ WERROR rpccli_srvsvc_net_share_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem switch(info_level) { case 1: ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, ctr->num_entries); + if (ctr->share.info1 == NULL) { + return WERR_NOMEM; + } memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1)); @@ -135,6 +138,9 @@ WERROR rpccli_srvsvc_net_share_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem break; case 2: ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, ctr->num_entries); + if (ctr->share.info2 == NULL) { + return WERR_NOMEM; + } memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2)); @@ -169,6 +175,10 @@ WERROR rpccli_srvsvc_net_share_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem /* adding info-level 502 here */ case 502: ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, ctr->num_entries); + + if (ctr->share.info502 == NULL) { + return WERR_NOMEM; + } memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502)); @@ -534,6 +544,9 @@ WERROR rpccli_srvsvc_net_file_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ switch(file_level) { case 3: ctr->file.info3 = TALLOC_ARRAY(mem_ctx, SRV_FILE_INFO_3, ctr->num_entries); + if (ctr->file.info3 == NULL) { + return WERR_NOMEM; + } memset(ctr->file.info3, 0, sizeof(SRV_FILE_INFO_3) * ctr->num_entries); diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c index 8cd6553a033..b56f36f5900 100644 --- a/source/rpc_parse/parse_misc.c +++ b/source/rpc_parse/parse_misc.c @@ -1107,6 +1107,7 @@ BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct * BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4) { + void *ptr; prs_debug(ps, depth, desc, "prs_unistr4"); depth++; @@ -1115,9 +1116,13 @@ BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4) if ( !prs_uint16("size", ps, depth, &uni4->size )) return False; - if ( !prs_pointer( desc, ps, depth, (void**)&uni4->string, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) ) + ptr = uni4->string; + + if ( !prs_pointer( desc, ps, depth, &ptr, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) ) return False; - + + uni4->string = (UNISTR2 *)ptr; + return True; } diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index f279c98c312..a936ef58709 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -746,6 +746,8 @@ static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto (*stot) = 0; } + + SAFE_FREE(session_list); } /******************************************************************* diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c index cbf638e7e62..1a204e70bc7 100644 --- a/source/rpcclient/cmd_samr.c +++ b/source/rpcclient/cmd_samr.c @@ -1680,7 +1680,12 @@ static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli, /* Look up names */ num_names = argc - 2; - names = TALLOC_ARRAY(mem_ctx, const char *, num_names); + if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) { + rpccli_samr_close(cli, mem_ctx, &domain_pol); + rpccli_samr_close(cli, mem_ctx, &connect_pol); + result = NT_STATUS_NO_MEMORY; + goto done; + } for (i = 0; i < argc - 2; i++) names[i] = argv[i + 2]; @@ -1747,6 +1752,12 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli, num_rids = argc - 2; rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids); + if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) { + rpccli_samr_close(cli, mem_ctx, &domain_pol); + rpccli_samr_close(cli, mem_ctx, &connect_pol); + result = NT_STATUS_NO_MEMORY; + goto done; + } for (i = 0; i < argc - 2; i++) sscanf(argv[i + 2], "%i", &rids[i]); diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c index f04b6a8ec9f..7f8bbbcd8c9 100644 --- a/source/rpcclient/cmd_spoolss.c +++ b/source/rpcclient/cmd_spoolss.c @@ -2454,6 +2454,10 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, option.count = option.ctr.count = 2; option.ctr.type = TALLOC_ARRAY(mem_ctx, SPOOL_NOTIFY_OPTION_TYPE, 2); + if (option.ctr.type == NULL) { + result = WERR_NOMEM; + goto done; + } ZERO_STRUCT(option.ctr.type[0]); option.ctr.type[0].type = PRINTER_NOTIFY_TYPE; diff --git a/source/script/tests/test_smbclient_s3.sh b/source/script/tests/test_smbclient_s3.sh index 007f3839f7d..d95657467d7 100755 --- a/source/script/tests/test_smbclient_s3.sh +++ b/source/script/tests/test_smbclient_s3.sh @@ -11,13 +11,75 @@ fi SERVER="$1" SERVER_IP="$2" +SMBCLIENT="$VALGRIND ${SMBCLIENT:-$SRCDIR/bin/smbclient} $CONFIGURATION" incdir=`dirname $0` . $incdir/test_functions.sh failed=0 -testit "smbclient -L $SERVER_IP" $VALGRIND $SRCDIR/bin/smbclient $CONFIGURATION -L $SERVER_IP -N -p 139 || failed=`expr $failed + 1` -testit "smbclient -L $SERVER" $VALGRIND $SRCDIR/bin/smbclient $CONFIGURATION -L $SERVER -N -p 139 || failed=`expr $failed + 1` +# Test that a noninteractive smbclient does not prompt +test_noninteractive_no_prompt() +{ + prompt="smb" + + echo du | \ + $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp 2>&1 | \ + grep $prompt + + if [ $? = 0 ] ; then + # got a prompt .. fail + echo matched interactive prompt in non-interactive mode + false + else + true + fi +} + +# Test that an interactive smbclient prompts to stdout +test_interactive_prompt_stdout() +{ + prompt="smb" + tmpfile=/tmp/smbclient.in.$$ + + cat > $tmpfile <<EOF +du +quit +EOF + + CLI_FORCE_INTERACTIVE=yes \ + $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp \ + < $tmpfile 2>/dev/null | \ + grep $prompt + + if [ $? = 0 ] ; then + # got a prompt .. succeed + rm -f $tmpfile + true + else + echo failed to match interactive prompt on stdout + rm -f $tmpfile + false + fi +} + +testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || failed=`expr $failed + 1` +testit "smbclient -L $SERVER" $SMBCLIENT -L $SERVER -N -p 139 || failed=`expr $failed + 1` + +testit "noninteractive smbclient does not prompt" \ + test_noninteractive_no_prompt || \ + failed=`expr $failed + 1` + +testit "noninteractive smbclient -l does not prompt" \ + test_noninteractive_no_prompt -l /tmp || \ + failed=`expr $failed + 1` + +testit "interactive smbclient prompts on stdout" \ + test_interactive_prompt_stdout || \ + failed=`expr $failed + 1` + +testit "interactive smbclient -l prompts on stdout" \ + test_interactive_prompt_stdout -l /tmp || \ + failed=`expr $failed + 1` testok $0 $failed diff --git a/source/script/tests/tests_smbclient_s3.sh b/source/script/tests/tests_smbclient_s3.sh new file mode 100644 index 00000000000..d48a692d4bd --- /dev/null +++ b/source/script/tests/tests_smbclient_s3.sh @@ -0,0 +1 @@ +. $SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP diff --git a/source/smbd/conn.c b/source/smbd/conn.c index 5aa8901d597..d857611c355 100644 --- a/source/smbd/conn.c +++ b/source/smbd/conn.c @@ -117,6 +117,10 @@ find_again: oldsz, newsz)); nbmap = bitmap_allocate(newsz); + if (!nbmap) { + DEBUG(0,("ERROR! malloc fail.\n")); + return NULL; + } bitmap_copy(nbmap, bmap); bitmap_free(bmap); diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 32503879099..e6dfc6506a0 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -369,8 +369,8 @@ static NTSTATUS handle_trans(connection_struct *conn, int name_offset = 0; DEBUG(3,("trans <%s> data=%u params=%u setup=%u\n", - state->name,state->total_data,state->total_param, - state->setup_count)); + state->name,(unsigned int)state->total_data,(unsigned int)state->total_param, + (unsigned int)state->setup_count)); /* * WinCE wierdness.... @@ -481,7 +481,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, state->data = SMB_MALLOC(state->total_data); if (state->data == NULL) { DEBUG(0,("reply_trans: data malloc fail for %u " - "bytes !\n", state->total_data)); + "bytes !\n", (unsigned int)state->total_data)); TALLOC_FREE(state); END_PROFILE(SMBtrans); return(ERROR_DOS(ERRDOS,ERRnomem)); @@ -501,7 +501,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, state->param = SMB_MALLOC(state->total_param); if (state->param == NULL) { DEBUG(0,("reply_trans: param malloc fail for %u " - "bytes !\n", state->total_param)); + "bytes !\n", (unsigned int)state->total_param)); SAFE_FREE(state->data); TALLOC_FREE(state); END_PROFILE(SMBtrans); diff --git a/source/smbd/notify_fam.c b/source/smbd/notify_fam.c index 3b6be77acab..b7f9a363321 100644 --- a/source/smbd/notify_fam.c +++ b/source/smbd/notify_fam.c @@ -371,7 +371,7 @@ fam_register_notify(connection_struct * conn, } if ((info = SMB_MALLOC_P(struct fam_req_info)) == NULL) { - DEBUG(0, ("malloc of %d bytes failed\n", sizeof(struct fam_req_info))); + DEBUG(0, ("malloc of %u bytes failed\n", (unsigned int)sizeof(struct fam_req_info))); return(NULL); } diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index 5d19d496fd9..e397139d2ef 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -914,7 +914,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", ****************************************************************************/ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count) { @@ -1063,6 +1063,10 @@ static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, struct ea_list *tmp; struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL); + if (!eal) { + return NULL; + } + DLIST_ADD_END(ea_list_head, eal, tmp); if (next_offset == 0) { break; @@ -1078,7 +1082,7 @@ static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, ****************************************************************************/ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { @@ -1818,11 +1822,11 @@ int reply_ntrename(connection_struct *conn, ****************************************************************************/ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { - char *setup = *ppsetup; + uint16 *setup = *ppsetup; files_struct *fsp; uint32 flags; @@ -1830,7 +1834,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, return ERROR_DOS(ERRDOS,ERRbadfunc); } - fsp = file_fsp(setup,4); + fsp = file_fsp((char *)setup,4); flags = IVAL(setup, 0); DEBUG(3,("call_nt_transact_notify_change\n")); @@ -1858,7 +1862,7 @@ name = %s\n", fsp->fsp_name )); ****************************************************************************/ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { @@ -1926,7 +1930,7 @@ static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd) ****************************************************************************/ static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { @@ -2042,7 +2046,7 @@ security descriptor.\n")); ****************************************************************************/ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { @@ -2088,7 +2092,7 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inb ****************************************************************************/ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { @@ -2113,7 +2117,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", function, fidnum, isFSctl, compfilter)); - fsp=file_fsp(*ppsetup, 4); + fsp=file_fsp((char *)*ppsetup, 4); /* this check is done in each implemented function case for now because I don't want to break anything... --metze FSP_BELONGS_CONN(fsp,conn);*/ @@ -2338,7 +2342,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou ****************************************************************************/ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { @@ -2594,7 +2598,7 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, ****************************************************************************/ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - char **ppsetup, uint32 setup_count, + uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) { @@ -2724,7 +2728,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_create); outsize = call_nt_transact_create(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); @@ -2737,7 +2741,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_ioctl); outsize = call_nt_transact_ioctl(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_ioctl); @@ -2749,7 +2753,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_set_security_desc); outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_set_security_desc); @@ -2761,7 +2765,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_notify_change); outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_notify_change); @@ -2773,7 +2777,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_rename); outsize = call_nt_transact_rename(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_rename); @@ -2785,7 +2789,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_query_security_desc); outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_query_security_desc); @@ -2798,7 +2802,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_get_user_quota); outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_get_user_quota); @@ -2810,7 +2814,7 @@ static int handle_nttrans(connection_struct *conn, START_PROFILE_NESTED(NT_transact_set_user_quota); outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, size, bufsize, - (char **)&state->setup, state->setup_count, + &state->setup, state->setup_count, &state->param, state->total_param, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_set_user_quota); @@ -2903,7 +2907,7 @@ int reply_nttrans(connection_struct *conn, * params and data. */ if ((state->data = SMB_MALLOC(state->total_data)) == NULL) { DEBUG(0,("reply_nttrans: data malloc fail for %u " - "bytes !\n", state->total_data)); + "bytes !\n", (unsigned int)state->total_data)); TALLOC_FREE(state); END_PROFILE(SMBnttrans); return(ERROR_DOS(ERRDOS,ERRnomem)); @@ -2922,7 +2926,7 @@ int reply_nttrans(connection_struct *conn, * params and data. */ if ((state->param = SMB_MALLOC(state->total_param)) == NULL) { DEBUG(0,("reply_nttrans: param malloc fail for %u " - "bytes !\n", state->total_param)); + "bytes !\n", (unsigned int)state->total_param)); SAFE_FREE(state->data); TALLOC_FREE(state); END_PROFILE(SMBnttrans); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 86743f626e6..27fd62be7fd 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -172,6 +172,11 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str for (i = 0, ea_namelist = TALLOC(mem_ctx, ea_namelist_size); i < 6; ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) { + + if (!ea_namelist) { + return NULL; + } + if (fsp && fsp->fh->fd != -1) { sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fh->fd, ea_namelist, ea_namelist_size); } else { @@ -5286,7 +5291,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, state->data = SMB_MALLOC(state->total_data); if (state->data == NULL) { DEBUG(0,("reply_trans2: data malloc fail for %u " - "bytes !\n", state->total_data)); + "bytes !\n", (unsigned int)state->total_data)); TALLOC_FREE(state); END_PROFILE(SMBtrans2); return(ERROR_DOS(ERRDOS,ERRnomem)); @@ -5306,7 +5311,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, state->param = SMB_MALLOC(state->total_param); if (state->param == NULL) { DEBUG(0,("reply_trans: param malloc fail for %u " - "bytes !\n", state->total_param)); + "bytes !\n", (unsigned int)state->total_param)); SAFE_FREE(state->data); TALLOC_FREE(state); END_PROFILE(SMBtrans2); diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c index e82eece0f96..fabf36e2527 100644 --- a/source/utils/net_ads.c +++ b/source/utils/net_ads.c @@ -863,8 +863,8 @@ static int check_ads_config( void ) if (strlen(global_myname()) > 15) { d_printf("Our netbios name can be at most 15 chars long, " - "\"%s\" is %d chars long\n", - global_myname(), strlen(global_myname())); + "\"%s\" is %u chars long\n", + global_myname(), (unsigned int)strlen(global_myname())); return -1; } @@ -1472,7 +1472,7 @@ static int net_ads_password(int argc, const char **argv) /* use the realm so we can eventually change passwords for users in realms other than default */ - if (!(ads = ads_init(realm, NULL, NULL))) { + if (!(ads = ads_init(realm, opt_workgroup, NULL))) { return -1; } @@ -1496,7 +1496,7 @@ static int net_ads_password(int argc, const char **argv) ret = kerberos_set_password(ads->auth.kdc_server, auth_principal, auth_password, user, new_password, ads->auth.time_offset); if (!ADS_ERR_OK(ret)) { - d_fprintf(stderr, "Password change failed :-( ...\n"); + d_fprintf(stderr, "Password change failed: %s\n", ads_errstr(ret)); ads_destroy(&ads); return -1; } diff --git a/source/utils/net_cache.c b/source/utils/net_cache.c index 69b3327f7a9..b90befcca2d 100644 --- a/source/utils/net_cache.c +++ b/source/utils/net_cache.c @@ -38,6 +38,7 @@ static void print_cache_entry(const char* keystr, const char* datastr, const time_t timeout, void* dptr) { char *timeout_str; + char *alloc_str = NULL; time_t now_t = time(NULL); struct tm timeout_tm, *now_tm; /* localtime returns statically allocated pointer, so timeout_tm @@ -64,12 +65,18 @@ static void print_cache_entry(const char* keystr, const char* datastr, } timeout_str[strlen(timeout_str) - 1] = '\0'; /* remove tailing CR */ } else { - asprintf(&timeout_str, "%.2d:%.2d:%.2d", timeout_tm.tm_hour, + asprintf(&alloc_str, "%.2d:%.2d:%.2d", timeout_tm.tm_hour, timeout_tm.tm_min, timeout_tm.tm_sec); + if (!alloc_str) { + return; + } + timeout_str = alloc_str; } d_printf("Key: %s\t Timeout: %s\t Value: %s %s\n", keystr, timeout_str, datastr, timeout > now_t ? "": "(expired)"); + + SAFE_FREE(alloc_str); } static void delete_cache_entry(const char* keystr, const char* datastr, diff --git a/source/utils/net_help.c b/source/utils/net_help.c index 40892ab0911..369fc095f21 100644 --- a/source/utils/net_help.c +++ b/source/utils/net_help.c @@ -73,7 +73,7 @@ int net_help_user(int argc, const char **argv) "\n\tDelete specified user\n"); d_printf("\nnet [<method>] user INFO <name> [misc. options] [targets]"\ "\n\tList the domain groups of the specified user\n"); - d_printf("\nnet [<method>] user ADD <name> [-c container] "\ + d_printf("\nnet [<method>] user ADD <name> [password] [-c container] "\ "[-F user flags] [misc. options]"\ " [targets]\n\tAdd specified user\n"); d_printf("\nnet [<method>] user RENAME <oldusername> <newusername>"\ diff --git a/source/utils/net_idmap.c b/source/utils/net_idmap.c index 0b5f68101ed..47e1f93b69f 100644 --- a/source/utils/net_idmap.c +++ b/source/utils/net_idmap.c @@ -193,7 +193,7 @@ static int net_idmap_restore(int argc, const char **argv) } while (!feof(stdin)) { - fstring line, sid_string; + fstring line, sid_string, fmt_string; int len; unid_t id; int type = ID_EMPTY; @@ -208,14 +208,15 @@ static int net_idmap_restore(int argc, const char **argv) line[len-1] = '\0'; /* Yuck - this is broken for sizeof(gid_t) != sizeof(int) */ - - if (sscanf(line, "GID %d %s", &id.gid, sid_string) == 2) { + snprintf(fmt_string, sizeof(fmt_string), "GID %%d %%%us", FSTRING_LEN); + if (sscanf(line, fmt_string, &id.gid, sid_string) == 2) { type = ID_GROUPID; } /* Yuck - this is broken for sizeof(uid_t) != sizeof(int) */ - if (sscanf(line, "UID %d %s", &id.uid, sid_string) == 2) { + snprintf(fmt_string, sizeof(fmt_string), "UID %%d %%%us", FSTRING_LEN); + if (sscanf(line, fmt_string, &id.uid, sid_string) == 2) { type = ID_USERID; } diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index 0844d407dbb..30d7b7be204 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -396,8 +396,8 @@ int net_rpc_join(int argc, const char **argv) if (strlen(global_myname()) > 15) { d_printf("Our netbios name can be at most 15 chars long, " - "\"%s\" is %d chars long\n", - global_myname(), strlen(global_myname())); + "\"%s\" is %u chars long\n", + global_myname(), (unsigned int)strlen(global_myname())); return -1; } @@ -583,7 +583,7 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, uint32 acb_info; uint32 unknown, user_rid; - if (argc != 1) { + if (argc < 1) { d_printf("User must be specified\n"); rpc_user_usage(argc, argv); return NT_STATUS_OK; @@ -620,6 +620,60 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, goto done; } + if (argc == 2) { + + uint32 *user_rids, num_rids, *name_types; + uint32 flags = 0x000003e8; /* Unknown */ + SAM_USERINFO_CTR ctr; + SAM_USER_INFO_24 p24; + uchar pwbuf[516]; + + result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, + flags, 1, &acct_name, + &num_rids, &user_rids, + &name_types); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + user_rids[0], &user_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Set password on account */ + + ZERO_STRUCT(ctr); + ZERO_STRUCT(p24); + + encode_pw_buffer(pwbuf, argv[1], STR_UNICODE); + + init_sam_user_info24(&p24, (char *)pwbuf,24); + + ctr.switch_value = 24; + ctr.info.id24 = &p24; + + result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24, + &cli->user_session_key, &ctr); + + if (!NT_STATUS_IS_OK(result)) { + d_fprintf(stderr, "Failed to set password for user %s - %s\n", + acct_name, nt_errstr(result)); + + result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol); + + if (!NT_STATUS_IS_OK(result)) { + d_fprintf(stderr, "Failed to delete user %s - %s\n", + acct_name, nt_errstr(result)); + return result; + } + } + + } done: if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Failed to add user %s - %s\n", acct_name, @@ -6611,6 +6665,7 @@ int net_rpc_usage(int argc, const char **argv) d_printf(" net rpc registry\t\tto manage registry hives\n"); d_printf(" net rpc service\t\tto start, stop and query services\n"); d_printf(" net rpc audit\t\t\tto modify global auditing settings\n"); + d_printf(" net rpc shell\t\t\tto open an interactive shell for remote server/account management\n"); d_printf("\n"); d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */ d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n"); diff --git a/source/utils/net_rpc_shell.c b/source/utils/net_rpc_shell.c index 4a4eadeef2b..63f514a79da 100644 --- a/source/utils/net_rpc_shell.c +++ b/source/utils/net_rpc_shell.c @@ -116,6 +116,10 @@ static BOOL net_sh_process(struct rpc_sh_ctx *ctx, } } + if (strequal(argv[0], "exit") || strequal(argv[0], "quit")) { + return False; + } + if (strequal(argv[0], "help") || strequal(argv[0], "?")) { for (c = ctx->cmds; c->name != NULL; c++) { if (ctx != this_ctx) { diff --git a/source/utils/net_sam.c b/source/utils/net_sam.c index 0bf662c2711..605d4bbc6bf 100644 --- a/source/utils/net_sam.c +++ b/source/utils/net_sam.c @@ -672,8 +672,8 @@ static int net_sam_listmem(int argc, const char **argv) return -1; } - d_printf("%s\\%s has %d members\n", groupdomain, groupname, - num_members); + d_printf("%s\\%s has %u members\n", groupdomain, groupname, + (unsigned int)num_members); for (i=0; i<num_members; i++) { const char *dom, *name; if (lookup_sid(tmp_talloc_ctx(), &members[i], diff --git a/source/utils/net_usershare.c b/source/utils/net_usershare.c index ca9ca4e6e21..253416c5cb0 100644 --- a/source/utils/net_usershare.c +++ b/source/utils/net_usershare.c @@ -259,11 +259,11 @@ static int get_share_list(TALLOC_CTX *ctx, const char *wcard, BOOL only_ours) return 0; } -enum priv_op { US_LIST_OP, US_INFO_OP}; +enum us_priv_op { US_LIST_OP, US_INFO_OP}; -struct priv_info { +struct us_priv_info { TALLOC_CTX *ctx; - enum priv_op op; + enum us_priv_op op; }; /*************************************************************************** @@ -290,7 +290,7 @@ static int info_fn(struct file_list *fl, void *priv) { SMB_STRUCT_STAT sbuf; char **lines = NULL; - struct priv_info *pi = (struct priv_info *)priv; + struct us_priv_info *pi = (struct us_priv_info *)priv; TALLOC_CTX *ctx = pi->ctx; int fd = -1; int numlines = 0; @@ -422,7 +422,7 @@ static int net_usershare_info(int argc, const char **argv) fstring wcard; BOOL only_ours = True; int ret = -1; - struct priv_info pi; + struct us_priv_info pi; TALLOC_CTX *ctx; fstrcpy(wcard, "*"); @@ -785,7 +785,7 @@ static int net_usershare_list(int argc, const char **argv) fstring wcard; BOOL only_ours = True; int ret = -1; - struct priv_info pi; + struct us_priv_info pi; TALLOC_CTX *ctx; fstrcpy(wcard, "*"); |