diff options
Diffstat (limited to 'source3')
39 files changed, 1273 insertions, 798 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 0ed7b4e898..db6f12321a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -735,7 +735,8 @@ MOUNT_OBJ = client/smbmount.o \ MNT_OBJ = client/smbmnt.o $(VERSION_OBJ) $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) -UMOUNT_OBJ = client/smbumount.o $(SOCKET_WRAPPER_OBJ) +UMOUNT_OBJ = client/smbumount.o $(SOCKET_WRAPPER_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) \ + $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) CIFS_MOUNT_OBJ = client/mount.cifs.o @@ -1188,7 +1189,7 @@ bin/smbmnt@EXEEXT@: $(BINARY_PREREQS) $(MNT_OBJ) bin/smbumount@EXEEXT@: $(BINARY_PREREQS) $(UMOUNT_OBJ) @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) + @$(CC) $(FLAGS) -o $@ $(UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @echo Linking $@ diff --git a/source3/client/smbmount.c b/source3/client/smbmount.c index 5e69cf92a3..99dc99f040 100644 --- a/source3/client/smbmount.c +++ b/source3/client/smbmount.c @@ -864,6 +864,7 @@ static void parse_mount_smb(int argc, char **argv) ****************************************************************************/ int main(int argc,char *argv[]) { + TALLOC_CTX *frame = talloc_stackframe(); char *p; DEBUGLEVEL = 1; @@ -940,5 +941,6 @@ static void parse_mount_smb(int argc, char **argv) strupper_m(my_netbios_name); init_mount(); + TALLOC_FREE(frame); return 0; } diff --git a/source3/client/smbumount.c b/source3/client/smbumount.c index 1664e4b555..e74c31299c 100644 --- a/source3/client/smbumount.c +++ b/source3/client/smbumount.c @@ -44,13 +44,13 @@ umount_ok(const char *mount_point) umount filesystems they don't own */ int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0); __kernel_uid32_t mount_uid; - + if (fid == -1) { fprintf(stderr, "Could not open %s: %s\n", mount_point, strerror(errno)); return -1; } - + if (ioctl(fid, SMB_IOC_GETMOUNTUID32, &mount_uid) != 0) { __kernel_uid_t mount_uid16; if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid16) != 0) { @@ -94,7 +94,7 @@ canonicalize (char *path) if (path == NULL) return NULL; - + if (realpath (path, canonical)) return canonical; @@ -104,7 +104,7 @@ canonicalize (char *path) } -int +int main(int argc, char *argv[]) { int fd; @@ -112,6 +112,7 @@ main(int argc, char *argv[]) struct mntent *mnt; FILE* mtab; FILE* new_mtab; + TALLOC_CTX *frame = talloc_stackframe(); if (argc != 2) { usage(); @@ -146,7 +147,7 @@ main(int argc, char *argv[]) return 1; } close(fd); - + if ((mtab = setmntent(MOUNTED, "r")) == NULL) { fprintf(stderr, "Can't open " MOUNTED ": %s\n", strerror(errno)); @@ -190,5 +191,6 @@ main(int argc, char *argv[]) return 1; } + TALLOC_FREE(frame); return 0; -} +} diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index da972f550f..0dfa88e87e 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -932,7 +932,7 @@ char *strdup_lower(const char *s) return out_buffer; } -static size_t ucs2_align(const void *base_ptr, const void *p, int flags) +size_t ucs2_align(const void *base_ptr, const void *p, int flags) { if (flags & (STR_NOALIGN|STR_ASCII)) return 0; diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a59b1d5ef2..e49db340ae 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -627,6 +627,18 @@ static int get_socket_port(int fd) } #endif +void set_sockaddr_port(struct sockaddr_storage *psa, uint16 port) +{ +#if defined(HAVE_IPV6) + if (psa->ss_family == AF_INET6) { + ((struct sockaddr_in6 *)psa)->sin6_port = htons(port); + } +#endif + if (psa->ss_family == AF_INET) { + ((struct sockaddr_in *)psa)->sin_port = htons(port); + } +} + const char *client_name(int fd) { return get_peer_name(fd,false); diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 1fef6ab239..45f09da85b 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -319,6 +319,25 @@ int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags) return pull_ucs2(NULL, dest, src, dest_len, src_len, flags|STR_UNICODE|STR_NOALIGN); } +/* Copy a string from little-endian or big-endian unicode source (depending + * on flags) to internal samba format destination. Allocates on talloc ctx. + */ + +int rpcstr_pull_talloc(TALLOC_CTX *ctx, + char **dest, + void *src, + int src_len, + int flags) +{ + return pull_ucs2_base_talloc(ctx, + NULL, + dest, + src, + src_len, + flags|STR_UNICODE|STR_NOALIGN); + +} + /* Copy a string from a unistr2 source to internal samba format destination. Use this instead of direct calls to rpcstr_pull() to avoid having to determine whether the source string is null terminated. */ diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index f259c21bdb..29e5661d3c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -829,13 +829,15 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, /* Insanity, sheer insanity..... */ if (strequal(realm, lp_realm())) { - pstring linkpath; + char linkpath[PATH_MAX+1]; int lret; lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath, sizeof(linkpath)-1); - linkpath[sizeof(pstring)-1] = '\0'; + if (lret != -1) { + linkpath[lret] = '\0'; + } - if (lret == 0 || strcmp(linkpath, fname) == 0) { + if (lret != -1 || strcmp(linkpath, fname) == 0) { /* Symlink already exists. */ TALLOC_FREE(dname); return True; @@ -843,6 +845,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, /* Try and replace with a symlink. */ if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { + const char *newpath = SYSTEM_KRB5_CONF_PATH ## ".saved"; if (errno != EEXIST) { DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " "of %s to %s failed. Errno %s\n", @@ -851,20 +854,17 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, return True; /* Not a fatal error. */ } - pstrcpy(linkpath, SYSTEM_KRB5_CONF_PATH); - pstrcat(linkpath, ".saved"); - /* Yes, this is a race conditon... too bad. */ - if (rename(SYSTEM_KRB5_CONF_PATH, linkpath) == -1) { + if (rename(SYSTEM_KRB5_CONF_PATH, newpath) == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: rename " "of %s to %s failed. Errno %s\n", - SYSTEM_KRB5_CONF_PATH, linkpath, + SYSTEM_KRB5_CONF_PATH, newpath, strerror(errno) )); TALLOC_FREE(dname); return True; /* Not a fatal error. */ } - if (symlink(fname, "/etc/krb5.conf") == -1) { + if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: " "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", fname, strerror(errno) )); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0294c4a5b5..01f6b00c02 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -251,7 +251,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) const char *c_realm; int count, i=0; struct ip_service *ip_list; - pstring realm; + const char *realm; bool got_realm = False; bool use_own_domain = False; char *sitename; @@ -261,7 +261,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) /* realm */ c_realm = ads->server.realm; - + if ( !c_realm || !*c_realm ) { /* special case where no realm and no workgroup means our own */ if ( !ads->server.workgroup || !*ads->server.workgroup ) { @@ -269,33 +269,33 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) c_realm = lp_realm(); } } - - if (c_realm && *c_realm) + + if (c_realm && *c_realm) got_realm = True; - - /* we need to try once with the realm name and fallback to the + + /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ - + if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; if (!c_realm || !*c_realm) { if ( use_own_domain ) c_realm = lp_workgroup(); } - + if ( !c_realm || !*c_realm ) { DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } } - - pstrcpy( realm, c_realm ); + + realm = c_realm; sitename = sitename_fetch(realm); again: - DEBUG(6,("ads_find_dc: looking for %s '%s'\n", + DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); @@ -305,7 +305,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) got_realm = False; goto again; } - + SAFE_FREE(sitename); return status; } @@ -338,7 +338,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) continue; } } - + if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); SAFE_FREE(sitename); diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 76194d5974..ac8846ad1e 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 Copyright (C) Andrew Bartlett 2002-2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -89,7 +89,9 @@ bool msrpc_gen(DATA_BLOB *blob, } va_end(ap); - /* allocate the space, then scan the format again to fill in the values */ + /* allocate the space, then scan the format + * again to fill in the values */ + *blob = data_blob(NULL, head_size + data_size); head_ofs = 0; @@ -104,7 +106,8 @@ bool msrpc_gen(DATA_BLOB *blob, SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); + push_string(NULL, blob->data+data_ofs, + s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; case 'A': @@ -113,7 +116,8 @@ bool msrpc_gen(DATA_BLOB *blob, SSVAL(blob->data, head_ofs, n); head_ofs += 2; SSVAL(blob->data, head_ofs, n); head_ofs += 2; SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + push_string(NULL, blob->data+data_ofs, + s, n, STR_ASCII|STR_NOALIGN); data_ofs += n; break; case 'a': @@ -159,7 +163,7 @@ bool msrpc_gen(DATA_BLOB *blob, } va_end(ap); - return True; + return true; } @@ -193,7 +197,6 @@ bool msrpc_parse(const DATA_BLOB *blob, uint16 len1, len2; uint32 ptr; uint32 *v; - pstring p; va_start(ap, format); for (i=0; format[i]; i++) { @@ -208,23 +211,37 @@ bool msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *ps = smb_xstrdup(""); } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; + /* make sure its in the right format + * be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || + (ptr + len1 < len1) || + (ptr + len1 > blob->length)) { + return false; } if (len1 & 1) { /* if odd length and unicode */ - return False; + return false; } - if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) - return False; + if (blob->data + ptr < + (uint8 *)(unsigned long)ptr || + blob->data + ptr < blob->data) + return false; if (0 < len1) { - pull_string( - NULL, 0, p, - blob->data + ptr, sizeof(p), - len1, STR_UNICODE|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + char *p = NULL; + pull_string_talloc(talloc_tos(), + NULL, + 0, + &p, + blob->data + ptr, + len1, + STR_UNICODE|STR_NOALIGN); + if (p) { + (*ps) = smb_xstrdup(p); + TALLOC_FREE(p); + } else { + (*ps) = smb_xstrdup(""); + } } else { (*ps) = smb_xstrdup(""); } @@ -241,19 +258,32 @@ bool msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *ps = smb_xstrdup(""); } else { - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; + if ((len1 != len2) || (ptr + len1 < ptr) || + (ptr + len1 < len1) || + (ptr + len1 > blob->length)) { + return false; } - if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) - return False; + if (blob->data + ptr < + (uint8 *)(unsigned long)ptr || + blob->data + ptr < blob->data) + return false; if (0 < len1) { - pull_string( - NULL, 0, p, - blob->data + ptr, sizeof(p), - len1, STR_ASCII|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + char *p = NULL; + pull_string_talloc(talloc_tos(), + NULL, + 0, + &p, + blob->data + ptr, + len1, + STR_ASCII|STR_NOALIGN); + if (p) { + (*ps) = smb_xstrdup(p); + TALLOC_FREE(p); + } else { + (*ps) = smb_xstrdup(""); + } } else { (*ps) = smb_xstrdup(""); } @@ -269,14 +299,19 @@ bool msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *b = data_blob_null; } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; + /* make sure its in the right format + * be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || + (ptr + len1 < len1) || + (ptr + len1 > blob->length)) { + return false; } - if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) - return False; - + if (blob->data + ptr < + (uint8 *)(unsigned long)ptr || + blob->data + ptr < blob->data) + return false; + *b = data_blob(blob->data + ptr, len1); } break; @@ -285,9 +320,11 @@ bool msrpc_parse(const DATA_BLOB *blob, len1 = va_arg(ap, unsigned); /* make sure its in the right format - be strict */ NEED_DATA(len1); - if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) - return False; - + if (blob->data + head_ofs < (uint8 *)head_ofs || + blob->data + head_ofs < blob->data) { + return false; + } + *b = data_blob(blob->data + head_ofs, len1); head_ofs += len1; break; @@ -299,15 +336,29 @@ bool msrpc_parse(const DATA_BLOB *blob, case 'C': s = va_arg(ap, char *); - if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) - return False; - - head_ofs += pull_string( - NULL, 0, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; + if (blob->data + head_ofs < (uint8 *)head_ofs || + blob->data + head_ofs < blob->data) { + return false; + } + + { + char *p = NULL; + size_t ret = pull_string_talloc(talloc_tos(), + NULL, + 0, + &p, + blob->data+head_ofs, + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (ret == (size_t)-1 || p == NULL) { + return false; + } + head_ofs += ret; + if (strcmp(s, p) != 0) { + TALLOC_FREE(p); + return false; + } + TALLOC_FREE(p); } break; } diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 2a1fe615ab..488a080287 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -1273,7 +1273,7 @@ enum { int main(int argc, char **argv, char **envp) { int opt; - + TALLOC_CTX *frame = talloc_stackframe(); poptContext pc; static char *string_arg; static char *opt_domain_name; @@ -1613,6 +1613,8 @@ int main(int argc, char **argv, char **envp) /* Exit code */ done: + talloc_destroy(frame); + poptFreeContext(pc); return result; } diff --git a/source3/pam_smbpass/pam_smb_auth.c b/source3/pam_smbpass/pam_smb_auth.c index b29f7c838f..79856a111d 100644 --- a/source3/pam_smbpass/pam_smb_auth.c +++ b/source3/pam_smbpass/pam_smb_auth.c @@ -170,98 +170,82 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { - int retval, *pretval = NULL; + int retval, *pretval = NULL; - retval = PAM_SUCCESS; + retval = PAM_SUCCESS; - pam_get_data(pamh, "smb_setcred_return", (const void **) &pretval); - if(pretval) { - retval = *pretval; - SAFE_FREE(pretval); - } - pam_set_data(pamh, "smb_setcred_return", NULL, NULL); + pam_get_data(pamh, "smb_setcred_return", (const void **) &pretval); + if(pretval) { + retval = *pretval; + SAFE_FREE(pretval); + } + pam_set_data(pamh, "smb_setcred_return", NULL, NULL); - return retval; + return retval; } - /* Helper function for adding a user to the db. */ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl, const char *name, struct samu *sampass, bool exist) { - pstring err_str; - pstring msg_str; - const char *pass = NULL; - int retval; - - err_str[0] = '\0'; - msg_str[0] = '\0'; - - /* Get the authtok; if we don't have one, silently fail. */ - retval = pam_get_item( pamh, PAM_AUTHTOK, (const void **) &pass ); - - if (retval != PAM_SUCCESS) { - _log_err( LOG_ALERT - , "pam_get_item returned error to pam_sm_authenticate" ); - return PAM_AUTHTOK_RECOVER_ERR; - } else if (pass == NULL) { - return PAM_AUTHTOK_RECOVER_ERR; - } - - /* Add the user to the db if they aren't already there. */ - if (!exist) { - retval = NT_STATUS_IS_OK(local_password_change( name, LOCAL_ADD_USER|LOCAL_SET_PASSWORD, - pass, err_str, - sizeof(err_str), - msg_str, sizeof(msg_str) )); - if (!retval && *err_str) - { - err_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str ); - } - else if (*msg_str) - { - msg_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str ); + char *err_str = NULL; + char *msg_str = NULL; + const char *pass = NULL; + int retval; + + /* Get the authtok; if we don't have one, silently fail. */ + retval = pam_get_item( pamh, PAM_AUTHTOK, (const void **) &pass ); + + if (retval != PAM_SUCCESS) { + _log_err( LOG_ALERT + , "pam_get_item returned error to pam_sm_authenticate" ); + return PAM_AUTHTOK_RECOVER_ERR; + } else if (pass == NULL) { + return PAM_AUTHTOK_RECOVER_ERR; } - pass = NULL; - return PAM_IGNORE; - } - else { - /* mimick 'update encrypted' as long as the 'no pw req' flag is not set */ - if ( pdb_get_acct_ctrl(sampass) & ~ACB_PWNOTREQ ) - { - retval = NT_STATUS_IS_OK(local_password_change( name, LOCAL_SET_PASSWORD, pass, err_str, sizeof(err_str), - msg_str, sizeof(msg_str) )); - if (!retval && *err_str) - { - err_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str ); - } - else if (*msg_str) - { - msg_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str ); + /* Add the user to the db if they aren't already there. */ + if (!exist) { + retval = NT_STATUS_IS_OK(local_password_change(name, LOCAL_ADD_USER|LOCAL_SET_PASSWORD, + pass, &err_str, &msg_str)); + if (!retval && err_str) { + make_remark(pamh, ctrl, PAM_ERROR_MSG, err_str ); + } else if (msg_str) { + make_remark(pamh, ctrl, PAM_TEXT_INFO, msg_str ); + } + pass = NULL; + + SAFE_FREE(err_str); + SAFE_FREE(msg_str); + return PAM_IGNORE; + } else { + /* mimick 'update encrypted' as long as the 'no pw req' flag is not set */ + if ( pdb_get_acct_ctrl(sampass) & ~ACB_PWNOTREQ ) { + retval = NT_STATUS_IS_OK(local_password_change(name, LOCAL_SET_PASSWORD, + pass, &err_str, &msg_str)); + if (!retval && err_str) { + make_remark(pamh, ctrl, PAM_ERROR_MSG, err_str ); + } else if (msg_str) { + make_remark(pamh, ctrl, PAM_TEXT_INFO, msg_str ); + } + } } - } - } - pass = NULL; - - return PAM_IGNORE; + SAFE_FREE(err_str); + SAFE_FREE(msg_str); + pass = NULL; + return PAM_IGNORE; } - /* static module data */ #ifdef PAM_STATIC struct pam_module _pam_smbpass_auth_modstruct = { - "pam_smbpass", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL + "pam_smbpass", + pam_sm_authenticate, + pam_sm_setcred, + NULL, + NULL, + NULL, + NULL }; #endif diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c index 25b7e2b623..f0fa018217 100644 --- a/source3/pam_smbpass/pam_smb_passwd.c +++ b/source3/pam_smbpass/pam_smb_passwd.c @@ -48,32 +48,29 @@ int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, const char *pass_new ) { int retval; - pstring err_str; - pstring msg_str; + char *err_str = NULL; + char *msg_str = NULL; - err_str[0] = '\0'; - msg_str[0] = '\0'; - - retval = NT_STATUS_IS_OK(local_password_change( user, LOCAL_SET_PASSWORD, pass_new, - err_str, sizeof(err_str), - msg_str, sizeof(msg_str) )); + retval = NT_STATUS_IS_OK(local_password_change(user, LOCAL_SET_PASSWORD, pass_new, + &err_str, + &msg_str)); if (!retval) { - if (*err_str) { - err_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str ); + if (err_str) { + make_remark(pamh, ctrl, PAM_ERROR_MSG, err_str ); } /* FIXME: what value is appropriate here? */ retval = PAM_AUTHTOK_ERR; } else { - if (*msg_str) { - msg_str[PSTRING_LEN-1] = '\0'; - make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str ); + if (msg_str) { + make_remark(pamh, ctrl, PAM_TEXT_INFO, msg_str ); } retval = PAM_SUCCESS; } + SAFE_FREE(err_str); + SAFE_FREE(msg_str); return retval; } diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index a9dd90eda1..2a4d4c4a0a 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -635,17 +635,18 @@ bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid, Change a password entry in the local smbpasswd file. *************************************************************/ -NTSTATUS local_password_change(const char *user_name, int local_flags, - const char *new_passwd, - char *err_str, size_t err_str_len, - char *msg_str, size_t msg_str_len) +NTSTATUS local_password_change(const char *user_name, + int local_flags, + const char *new_passwd, + char **pp_err_str, + char **pp_msg_str) { struct samu *sam_pass=NULL; uint32 other_acb; NTSTATUS result; - *err_str = '\0'; - *msg_str = '\0'; + *pp_err_str = NULL; + *pp_msg_str = NULL; /* Get the smb passwd entry for this user */ @@ -689,12 +690,12 @@ NTSTATUS local_password_change(const char *user_name, int local_flags, } if (!NT_STATUS_IS_OK(result)) { - slprintf(err_str, err_str_len-1, "Failed to " "initialize account for user %s: %s\n", + asprintf(pp_err_str, "Failed to " "initialize account for user %s: %s\n", user_name, nt_errstr(result)); return result; } } else { - slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to find entry for user %s.\n", user_name); return NT_STATUS_NO_SUCH_USER; } } else { @@ -707,19 +708,19 @@ NTSTATUS local_password_change(const char *user_name, int local_flags, other_acb = (pdb_get_acct_ctrl(sam_pass) & (~(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL))); if (local_flags & LOCAL_TRUST_ACCOUNT) { if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) { - slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) { - slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to set 'domain trust account' flags for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } } else { if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) { - slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to set 'normal account' flags for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } @@ -732,13 +733,13 @@ NTSTATUS local_password_change(const char *user_name, int local_flags, if (local_flags & LOCAL_DISABLE_USER) { if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to set 'disabled' flag for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } } else if (local_flags & LOCAL_ENABLE_USER) { if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } @@ -746,7 +747,7 @@ NTSTATUS local_password_change(const char *user_name, int local_flags, if (local_flags & LOCAL_SET_NO_PASSWORD) { if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to set 'no password required' flag for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } @@ -762,19 +763,19 @@ NTSTATUS local_password_change(const char *user_name, int local_flags, */ if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) { if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } } if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to unset 'no password required' flag for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) { - slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to set password for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } @@ -782,34 +783,34 @@ NTSTATUS local_password_change(const char *user_name, int local_flags, if (local_flags & LOCAL_ADD_USER) { if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) { - slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name); + asprintf(pp_msg_str, "Added user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_OK; } else { - slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to add entry for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } } else if (local_flags & LOCAL_DELETE_USER) { if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) { - slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to delete entry for user %s.\n", user_name); TALLOC_FREE(sam_pass); return NT_STATUS_UNSUCCESSFUL; } - slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name); + asprintf(pp_msg_str, "Deleted user %s.\n", user_name); } else { result = pdb_update_sam_account(sam_pass); if(!NT_STATUS_IS_OK(result)) { - slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name); + asprintf(pp_err_str, "Failed to modify entry for user %s.\n", user_name); TALLOC_FREE(sam_pass); return result; } if(local_flags & LOCAL_DISABLE_USER) - slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name); + asprintf(pp_msg_str, "Disabled user %s.\n", user_name); else if (local_flags & LOCAL_ENABLE_USER) - slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name); + asprintf(pp_msg_str, "Enabled user %s.\n", user_name); else if (local_flags & LOCAL_SET_NO_PASSWORD) - slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name); + asprintf(pp_msg_str, "User %s password set to none.\n", user_name); } TALLOC_FREE(sam_pass); @@ -864,7 +865,7 @@ bool init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen) uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen; uint32 pwHistLen = 0; bool ret = True; - fstring tmpstring; + fstring tmp_string; bool expand_explicit = lp_passdb_expand_explicit(); if(sampass == NULL || buf == NULL) { @@ -930,12 +931,12 @@ bool init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen) pdb_set_fullname(sampass, fullname, PDB_SET); if (homedir) { - fstrcpy( tmpstring, homedir ); + fstrcpy( tmp_string, homedir ); if (expand_explicit) { - standard_sub_basic( username, domain, tmpstring, - sizeof(tmpstring) ); + standard_sub_basic( username, domain, tmp_string, + sizeof(tmp_string) ); } - pdb_set_homedir(sampass, tmpstring, PDB_SET); + pdb_set_homedir(sampass, tmp_string, PDB_SET); } else { pdb_set_homedir(sampass, @@ -950,12 +951,12 @@ bool init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen) pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT ); if (logon_script) { - fstrcpy( tmpstring, logon_script ); + fstrcpy( tmp_string, logon_script ); if (expand_explicit) { - standard_sub_basic( username, domain, tmpstring, - sizeof(tmpstring) ); + standard_sub_basic( username, domain, tmp_string, + sizeof(tmp_string) ); } - pdb_set_logon_script(sampass, tmpstring, PDB_SET); + pdb_set_logon_script(sampass, tmp_string, PDB_SET); } else { pdb_set_logon_script(sampass, @@ -965,12 +966,12 @@ bool init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen) } if (profile_path) { - fstrcpy( tmpstring, profile_path ); + fstrcpy( tmp_string, profile_path ); if (expand_explicit) { - standard_sub_basic( username, domain, tmpstring, - sizeof(tmpstring) ); + standard_sub_basic( username, domain, tmp_string, + sizeof(tmp_string) ); } - pdb_set_profile_path(sampass, tmpstring, PDB_SET); + pdb_set_profile_path(sampass, tmp_string, PDB_SET); } else { pdb_set_profile_path(sampass, diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index aaba91620b..e8bea19152 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -29,7 +29,7 @@ /** * @todo Redefine this to NULL, but this changes the API because * much of samba assumes that the pdb_get...() funtions - * return pstrings. (ie not null-pointers). + * return strings. (ie not null-pointers). * See also pdb_fill_default_sam(). */ diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index c55d325080..0159932e34 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -182,18 +182,20 @@ static struct pdb_methods *pdb_get_methods_reload( bool reload ) if ( pdb && reload ) { pdb->free_private_data( &(pdb->private_data) ); if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) { - pstring msg; - slprintf(msg, sizeof(msg)-1, "pdb_get_methods_reload: failed to get pdb methods for backend %s\n", - lp_passdb_backend() ); + char *msg = NULL; + asprintf(&msg, "pdb_get_methods_reload: " + "failed to get pdb methods for backend %s\n", + lp_passdb_backend()); smb_panic(msg); } } if ( !pdb ) { if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) { - pstring msg; - slprintf(msg, sizeof(msg)-1, "pdb_get_methods_reload: failed to get pdb methods for backend %s\n", - lp_passdb_backend() ); + char *msg = NULL; + asprintf(&msg, "pdb_get_methods_reload: " + "failed to get pdb methods for backend %s\n", + lp_passdb_backend()); smb_panic(msg); } } @@ -319,17 +321,19 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods, } if ( !(pwd = Get_Pwnam_alloc(tmp_ctx, name)) ) { - pstring add_script; + char *add_script = NULL; int add_ret; fstring name2; if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') { - pstrcpy(add_script, lp_adduser_script()); + add_script = talloc_strdup(tmp_ctx, + lp_adduser_script()); } else { - pstrcpy(add_script, lp_addmachine_script()); + add_script = talloc_strdup(tmp_ctx, + lp_addmachine_script()); } - if (add_script[0] == '\0') { + if (!add_script || add_script[0] == '\0') { DEBUG(3, ("Could not find user %s and no add script " "defined\n", name)); return NT_STATUS_NO_SUCH_USER; @@ -339,7 +343,13 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods, compatibility with previous Samba releases */ fstrcpy( name2, name ); strlower_m( name2 ); - all_string_sub(add_script, "%u", name2, sizeof(add_script)); + add_script = talloc_all_string_sub(tmp_ctx, + add_script, + "%u", + name2); + if (!add_script) { + return NT_STATUS_NO_MEMORY; + } add_ret = smbrun(add_script,NULL); DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret)); @@ -399,7 +409,7 @@ NTSTATUS pdb_create_user(TALLOC_CTX *mem_ctx, const char *name, uint32 flags, static int smb_delete_user(const char *unix_user) { - pstring del_script; + char *del_script = NULL; int ret; /* safety check */ @@ -409,10 +419,17 @@ static int smb_delete_user(const char *unix_user) return -1; } - pstrcpy(del_script, lp_deluser_script()); - if (! *del_script) + del_script = talloc_strdup(talloc_tos(), lp_deluser_script()); + if (!del_script || !*del_script) { + return -1; + } + del_script = talloc_all_string_sub(talloc_tos(), + del_script, + "%u", + unix_user); + if (!del_script) { return -1; - all_string_sub(del_script, "%u", unix_user, sizeof(del_script)); + } ret = smbrun(del_script,NULL); flush_pwnam_cache(); if (ret == 0) { diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 0cec76227b..139aa14155 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -53,7 +53,7 @@ struct smbpasswd_privates /* formerly static variables */ struct smb_passwd pw_buf; - pstring user_name; + fstring user_name; unsigned char smbpwd[16]; unsigned char smbntpwd[16]; @@ -437,12 +437,6 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s continue; } - /* - * As 256 is shorter than a pstring we don't need to check - * length here - if this ever changes.... - */ - SMB_ASSERT(sizeof(pstring) > sizeof(linebuf)); - strncpy(user_name, linebuf, PTR_DIFF(p, linebuf)); user_name[PTR_DIFF(p, linebuf)] = '\0'; @@ -731,7 +725,7 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", static bool mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd) { /* Static buffers we will return. */ - pstring user_name; + fstring user_name; char *status; char linebuf[256]; @@ -847,13 +841,6 @@ static bool mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con continue; } - /* - * As 256 is shorter than a pstring we don't need to check - * length here - if this ever changes.... - */ - - SMB_ASSERT(sizeof(user_name) > sizeof(linebuf)); - strncpy(user_name, linebuf, PTR_DIFF(p, linebuf)); user_name[PTR_DIFF(p, linebuf)] = '\0'; if (strequal(user_name, pwd->smb_name)) { @@ -1091,13 +1078,18 @@ This is no longer supported.!\n", pwd->smb_name)); static bool del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name) { const char *pfile = smbpasswd_state->smbpasswd_file; - pstring pfile2; + char *pfile2 = NULL; struct smb_passwd *pwd = NULL; FILE *fp = NULL; FILE *fp_write = NULL; int pfile2_lockdepth = 0; - slprintf(pfile2, sizeof(pfile2)-1, "%s.%u", pfile, (unsigned)sys_getpid() ); + pfile2 = talloc_asprintf(talloc_tos(), + "%s.%u", + pfile, (unsigned)sys_getpid()); + if (!pfile2) { + return false; + } /* * Open the smbpassword file - for update. It needs to be update @@ -1179,7 +1171,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno))); if(rename(pfile2,pfile) != 0) { unlink(pfile2); } - + endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth); endsmbfilepwent(fp_write,&pfile2_lockdepth); return True; @@ -1511,9 +1503,10 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods, struct samu *old_acct, const char *newname) { - pstring rename_script; + char *rename_script = NULL; struct samu *new_acct = NULL; bool interim_account = False; + TALLOC_CTX *ctx = talloc_tos(); NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; if (!*(lp_renameuser_script())) @@ -1528,7 +1521,7 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods, { goto done; } - + ret = smbpasswd_add_sam_account(my_methods, new_acct); if (!NT_STATUS_IS_OK(ret)) goto done; @@ -1536,15 +1529,38 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods, interim_account = True; /* rename the posix user */ - pstrcpy(rename_script, lp_renameuser_script()); + rename_script = talloc_strdup(ctx, + lp_renameuser_script()); + if (!rename_script) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } if (*rename_script) { int rename_ret; - string_sub2(rename_script, "%unew", newname, sizeof(pstring), - True, False, True); - string_sub2(rename_script, "%uold", pdb_get_username(old_acct), - sizeof(pstring), True, False, True); + rename_script = talloc_string_sub2(ctx, + rename_script, + "%unew", + newname, + true, + false, + true); + if (!rename_script) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + rename_script = talloc_string_sub2(ctx, + rename_script, + "%uold", + pdb_get_username(old_acct), + true, + false, + true); + if (!rename_script) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } rename_ret = smbrun(rename_script, NULL); @@ -1554,8 +1570,8 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods, smb_nscd_flush_user_cache(); } - if (rename_ret) - goto done; + if (rename_ret) + goto done; } else { goto done; } @@ -1563,7 +1579,7 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods, smbpasswd_delete_sam_account(my_methods, old_acct); interim_account = False; -done: +done: /* cleanup */ if (interim_account) smbpasswd_delete_sam_account(my_methods, new_acct); diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 099b443072..fe8497c939 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -481,7 +481,7 @@ bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen) uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen; uint32 pwHistLen = 0; bool ret = True; - fstring tmpstring; + fstring tmp_string; bool expand_explicit = lp_passdb_expand_explicit(); if(sampass == NULL || buf == NULL) { @@ -546,12 +546,12 @@ bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen) pdb_set_fullname(sampass, fullname, PDB_SET); if (homedir) { - fstrcpy( tmpstring, homedir ); + fstrcpy( tmp_string, homedir ); if (expand_explicit) { - standard_sub_basic( username, domain, tmpstring, - sizeof(tmpstring) ); + standard_sub_basic( username, domain, tmp_string, + sizeof(tmp_string) ); } - pdb_set_homedir(sampass, tmpstring, PDB_SET); + pdb_set_homedir(sampass, tmp_string, PDB_SET); } else { pdb_set_homedir(sampass, @@ -566,12 +566,12 @@ bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen) pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT ); if (logon_script) { - fstrcpy( tmpstring, logon_script ); + fstrcpy( tmp_string, logon_script ); if (expand_explicit) { - standard_sub_basic( username, domain, tmpstring, - sizeof(tmpstring) ); + standard_sub_basic( username, domain, tmp_string, + sizeof(tmp_string) ); } - pdb_set_logon_script(sampass, tmpstring, PDB_SET); + pdb_set_logon_script(sampass, tmp_string, PDB_SET); } else { pdb_set_logon_script(sampass, @@ -581,12 +581,12 @@ bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen) } if (profile_path) { - fstrcpy( tmpstring, profile_path ); + fstrcpy( tmp_string, profile_path ); if (expand_explicit) { - standard_sub_basic( username, domain, tmpstring, - sizeof(tmpstring) ); + standard_sub_basic( username, domain, tmp_string, + sizeof(tmp_string) ); } - pdb_set_profile_path(sampass, tmpstring, PDB_SET); + pdb_set_profile_path(sampass, tmp_string, PDB_SET); } else { pdb_set_profile_path(sampass, @@ -1375,40 +1375,43 @@ static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, struct s - unlock the new user record ***************************************************************************/ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, - struct samu *old_acct, + struct samu *old_acct, const char *newname) { + TALLOC_CTX *ctx = talloc_tos(); struct samu *new_acct = NULL; - pstring rename_script; + char *rename_script = NULL; bool interim_account = False; int rename_ret; fstring oldname_lower; fstring newname_lower; /* can't do anything without an external script */ - - pstrcpy(rename_script, lp_renameuser_script() ); - if ( ! *rename_script ) { + + rename_script = talloc_strdup(ctx, lp_renameuser_script()); + if (!rename_script) { + return NT_STATUS_NO_MEMORY; + } + if (!*rename_script) { return NT_STATUS_ACCESS_DENIED; } /* invalidate the existing TDB iterator if it is open */ - + tdbsam_endsampwent( my_methods ); if ( !(new_acct = samu_new( NULL )) ) { return NT_STATUS_NO_MEMORY; } - - if ( !pdb_copy_sam_account(new_acct, old_acct) - || !pdb_set_username(new_acct, newname, PDB_CHANGED)) + + if ( !pdb_copy_sam_account(new_acct, old_acct) + || !pdb_set_username(new_acct, newname, PDB_CHANGED)) { TALLOC_FREE(new_acct ); return NT_STATUS_NO_MEMORY; } /* open the database */ - if ( !tdbsam_open( tdbsam_filename ) ) { DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename)); TALLOC_FREE(new_acct ); @@ -1416,11 +1419,10 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, } /* add the new account and lock it */ - if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) { goto done; } - + interim_account = True; if ( tdb_lock_bystring_with_timeout(tdbsam, newname, 30) == -1 ) { @@ -1436,24 +1438,41 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, fstrcpy( newname_lower, newname ); strlower_m( newname_lower ); - string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring), - True, False, True); - string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring), - True, False, True); + rename_script = talloc_string_sub2(ctx, + rename_script, + "%unew", + newname_lower, + true, + false, + true); + if (!rename_script) { + goto done; + } + rename_script = talloc_string_sub2(ctx, + rename_script, + "%uold", + oldname_lower, + true, + false, + true); + if (!rename_script) { + goto done; + } rename_ret = smbrun(rename_script, NULL); - DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret)); + DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", + rename_script, rename_ret)); if (rename_ret == 0) { smb_nscd_flush_user_cache(); } if (rename_ret) { - goto done; + goto done; } /* rewrite the rid->username record */ - + if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) { goto done; } @@ -1461,21 +1480,21 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, tdb_unlock_bystring( tdbsam, newname ); tdb_delete_samacct_only( old_acct ); - + tdbsam_close(); - + TALLOC_FREE(new_acct ); return NT_STATUS_OK; -done: +done: /* cleanup */ if (interim_account) { tdb_unlock_bystring(tdbsam, newname); tdb_delete_samacct_only(new_acct); } - + tdbsam_close(); - + if (new_acct) TALLOC_FREE(new_acct); @@ -1581,7 +1600,7 @@ static bool tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid) static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *location) { NTSTATUS nt_status; - pstring tdbfile; + char *tdbfile = NULL; const char *pfile = location; if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) { @@ -1604,15 +1623,21 @@ static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *loc (*pdb_method)->new_rid = tdbsam_new_rid; /* save the path for later */ - - if ( !location ) { - pstr_sprintf( tdbfile, "%s/%s", dyn_STATEDIR(), PASSDB_FILE_NAME ); + + if (!location) { + if (asprintf(&tdbfile, "%s/%s", dyn_STATEDIR(), PASSDB_FILE_NAME) < 0) { + return NT_STATUS_NO_MEMORY; + } pfile = tdbfile; } tdbsam_filename = SMB_STRDUP(pfile); + if (!tdbsam_filename) { + return NT_STATUS_NO_MEMORY; + } + SAFE_FREE(tdbfile); /* no private data */ - + (*pdb_method)->private_data = NULL; (*pdb_method)->free_private_data = NULL; diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index a7221df6df..c760198b2d 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -51,22 +51,35 @@ static void get_rand_seed(int *new_seed) /* open up the secrets database */ bool secrets_init(void) { - pstring fname; + TALLOC_CTX *ctx; + char *fname = NULL; unsigned char dummy; if (tdb) return True; - pstrcpy(fname, lp_private_dir()); - pstrcat(fname,"/secrets.tdb"); + ctx = talloc_init("secrets_init"); + if (!ctx) { + return false; + } + fname = talloc_asprintf(ctx, + "%s/secrets.tdb", + lp_private_dir()); + if (!fname) { + TALLOC_FREE(ctx); + return false; + } tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (!tdb) { DEBUG(0,("Failed to open %s\n", fname)); + TALLOC_FREE(ctx); return False; } + TALLOC_FREE(ctx); + /** * Set a reseed function for the crypto random generator * @@ -337,20 +350,36 @@ static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid) { int idx; size_t len = 0; + uint8 *p = pack_buf; + int remaining_space = pack_buf ? bufsize : 0; - if (!sid || !pack_buf) return -1; + if (!sid) { + return -1; + } - len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num, + len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num, sid->num_auths); + if (pack_buf) { + p += len; + remaining_space -= len; + } for (idx = 0; idx < 6; idx++) { - len += tdb_pack(pack_buf + len, bufsize - len, "b", + len += tdb_pack(p, remaining_space, "b", sid->id_auth[idx]); + if (pack_buf) { + p += len; + remaining_space -= len; + } } for (idx = 0; idx < MAXSUBAUTHS; idx++) { - len += tdb_pack(pack_buf + len, bufsize - len, "d", + len += tdb_pack(p, remaining_space, "d", sid->sub_auths[idx]); + if (pack_buf) { + p += len; + remaining_space -= len; + } } return len; @@ -400,22 +429,43 @@ static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize, TRUSTED_DOM_PASS* pass) { int idx, len = 0; + uint8 *p = pack_buf; + int remaining_space = pack_buf ? bufsize : 0; - if (!pack_buf || !pass) return -1; + if (!pass) { + return -1; + } /* packing unicode domain name and password */ - len += tdb_pack(pack_buf + len, bufsize - len, "d", + len += tdb_pack(p, remaining_space, "d", pass->uni_name_len); + if (pack_buf) { + p += len; + remaining_space -= len; + } - for (idx = 0; idx < 32; idx++) - len += tdb_pack(pack_buf + len, bufsize - len, "w", + for (idx = 0; idx < 32; idx++) { + len += tdb_pack(p, remaining_space, "w", pass->uni_name[idx]); + if (pack_buf) { + p += len; + remaining_space -= len; + } + } - len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len, + len += tdb_pack(p, remaining_space, "dPd", pass->pass_len, pass->pass, pass->mod_time); + if (pack_buf) { + p += len; + remaining_space -= len; + } /* packing SID structure */ - len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid); + len += tdb_sid_pack(p, remaining_space, &pass->domain_sid); + if (pack_buf) { + p += len; + remaining_space -= len; + } return len; } @@ -531,11 +581,11 @@ bool secrets_store_trusted_domain_password(const char* domain, const char* pwd, const DOM_SID *sid) { smb_ucs2_t *uni_dom_name; + bool ret; /* packing structures */ - pstring pass_buf; + uint8 *pass_buf = NULL; int pass_len = 0; - int pass_buf_len = sizeof(pass_buf); struct trusted_dom_pass pass; ZERO_STRUCT(pass); @@ -560,9 +610,17 @@ bool secrets_store_trusted_domain_password(const char* domain, const char* pwd, /* domain sid */ sid_copy(&pass.domain_sid, sid); - pass_len = tdb_trusted_dom_pass_pack((uint8 *)pass_buf, pass_buf_len, &pass); - - return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len); + /* Calculate the length. */ + pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass); + pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len); + if (!pass_buf) { + return false; + } + pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass); + ret = secrets_store(trustdom_keystr(domain), (void *)&pass_buf, + pass_len); + SAFE_FREE(pass_buf); + return ret; } /************************************************************************ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 1d218bac3d..bbe312ca27 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -228,18 +228,17 @@ static const struct table_node archi_table[]= { generate a new TDB_DATA key for storing a printer ****************************************************************************/ -static TDB_DATA make_printer_tdbkey( const char *sharename ) +static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename ) { fstring share; - static pstring keystr; + char *keystr = NULL; TDB_DATA key; - - fstrcpy( share, sharename ); - strlower_m( share ); - - pstr_sprintf( keystr, "%s%s", PRINTERS_PREFIX, share ); - - key = string_term_tdb_data(keystr); + + fstrcpy(share, sharename); + strlower_m(share); + + keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share); + key = string_term_tdb_data(keystr ? keystr : ""); return key; } @@ -248,18 +247,18 @@ static TDB_DATA make_printer_tdbkey( const char *sharename ) generate a new TDB_DATA key for storing a printer security descriptor ****************************************************************************/ -static TDB_DATA make_printers_secdesc_tdbkey( const char* sharename ) +static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx, + const char* sharename ) { fstring share; - static pstring keystr; + char *keystr = NULL; TDB_DATA key; - fstrcpy( share, sharename ); - strlower_m( share ); - - pstr_sprintf( keystr, "%s%s", SECDESC_PREFIX, share ); + fstrcpy(share, sharename ); + strlower_m(share); - key = string_term_tdb_data(keystr); + keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share); + key = string_term_tdb_data(keystr ? keystr : ""); return key; } @@ -482,38 +481,39 @@ static bool upgrade_to_version_4(void) static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA data, void *state ) { + TALLOC_CTX *ctx = talloc_tos(); TDB_DATA new_key; - + if (!data.dptr || data.dsize == 0) return 0; /* upgrade printer records and security descriptors */ - + if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) { - new_key = make_printer_tdbkey( (const char *)key.dptr+strlen(PRINTERS_PREFIX) ); + new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) ); } else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) { - new_key = make_printers_secdesc_tdbkey( (const char *)key.dptr+strlen(SECDESC_PREFIX) ); + new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) ); } else { /* ignore this record */ return 0; } - + /* delete the original record and store under the normalized key */ - + if ( tdb_delete( the_tdb, key ) != 0 ) { DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n", key.dptr)); return 1; } - + if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) { DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n", key.dptr)); return 1; } - + return 0; } @@ -830,24 +830,46 @@ int get_ntforms(nt_forms_struct **list) /**************************************************************************** write a form struct list ****************************************************************************/ + int write_ntforms(nt_forms_struct **list, int number) { - pstring buf, key; + TALLOC_CTX *ctx = talloc_tos(); + char *buf = NULL; + char *key = NULL; int len; TDB_DATA dbuf; int i; for (i=0;i<number;i++) { /* save index, so list is rebuilt in correct order */ - len = tdb_pack((uint8 *)buf, sizeof(buf), "dddddddd", + len = tdb_pack(NULL, 0, "dddddddd", i, (*list)[i].flag, (*list)[i].width, (*list)[i].length, (*list)[i].left, (*list)[i].top, (*list)[i].right, (*list)[i].bottom); - if (len > sizeof(buf)) break; - slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name); + if (!len) { + continue; + } + buf = TALLOC_ARRAY(ctx, char, len); + if (!buf) { + return 0; + } + len = tdb_pack((uint8 *)buf, len, "dddddddd", + i, (*list)[i].flag, (*list)[i].width, (*list)[i].length, + (*list)[i].left, (*list)[i].top, (*list)[i].right, + (*list)[i].bottom); + key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name); + if (!key) { + return 0; + } dbuf.dsize = len; dbuf.dptr = (uint8 *)buf; - if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) break; + if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) { + TALLOC_FREE(key); + TALLOC_FREE(buf); + break; + } + TALLOC_FREE(key); + TALLOC_FREE(buf); } return i; @@ -907,7 +929,7 @@ bool add_a_form(nt_forms_struct **list, const FORM *form, int *count) bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret) { - pstring key; + char *key = NULL; int n=0; fstring form_name; @@ -928,13 +950,17 @@ bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR return False; } - slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name); + if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) { + *ret = WERR_NOMEM; + return false; + } if (tdb_delete_bystring(tdb_forms, key) != 0) { + SAFE_FREE(key); *ret = WERR_NOMEM; return False; } - - return True; + SAFE_FREE(key); + return true; } /**************************************************************************** @@ -973,7 +999,7 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version) { int total=0; const char *short_archi; - pstring key; + char *key = NULL; TDB_DATA kbuf, newkey; short_archi = get_short_archi(architecture); @@ -981,7 +1007,10 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version) return 0; } - slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version); + if (asprintf(&key, "%s%s/%d/", DRIVERS_PREFIX, + short_archi, version) < 0) { + return 0; + } for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr; @@ -989,9 +1018,10 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version) if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0) continue; - + if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) { DEBUG(0,("get_ntdrivers: failed to enlarge list!\n")); + SAFE_FREE(key); return -1; } @@ -999,6 +1029,7 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version) total++; } + SAFE_FREE(key); return(total); } @@ -2063,13 +2094,15 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract /**************************************************************************** ****************************************************************************/ + static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) { + TALLOC_CTX *ctx = talloc_tos(); int len, buflen; const char *architecture; - pstring directory; + char *directory = NULL; fstring temp_name; - pstring key; + char *key = NULL; uint8 *buf; int i, ret; TDB_DATA dbuf; @@ -2084,7 +2117,11 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) * It does make sense to NOT store the server's name in the printer TDB. */ - slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion); + directory = talloc_asprintf(ctx, "\\print$\\%s\\%d\\", + architecture, driver->cversion); + if (!directory) { + return (uint32)-1; + } /* .inf files do not always list a file for each of the four standard files. * Don't prepend a path to a null filename, or client claims: @@ -2119,7 +2156,11 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) } } - slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name); + key = talloc_asprintf(ctx, "%s%s/%d/%s", DRIVERS_PREFIX, + architecture, driver->cversion, driver->name); + if (!key) { + return (uint32)-1; + } DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key )); @@ -2159,7 +2200,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) dbuf.dptr = buf; dbuf.dsize = len; - + ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE); done: @@ -2232,7 +2273,7 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const char *architecture; int len = 0; int i; - pstring key; + char *key = NULL; ZERO_STRUCT(driver); @@ -2240,19 +2281,24 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, if ( !architecture ) { return WERR_UNKNOWN_PRINTER_DRIVER; } - + /* Windows 4.0 (i.e. win9x) should always use a version of 0 */ - + if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 ) version = 0; DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername)); - slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername); - + if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX, + architecture, version, drivername) < 0) { + return WERR_NOMEM; + } + dbuf = tdb_fetch_bystring(tdb_drivers, key); - if (!dbuf.dptr) + if (!dbuf.dptr) { + SAFE_FREE(key); return WERR_UNKNOWN_PRINTER_DRIVER; + } len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", &driver.cversion, @@ -2277,11 +2323,12 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, &driver.dependentfiles[i]); i++; } - + if ( driver.dependentfiles ) fstrcpy( driver.dependentfiles[i], "" ); SAFE_FREE(dbuf.dptr); + SAFE_FREE(key); if (len != dbuf.dsize) { SAFE_FREE(driver.dependentfiles); @@ -2397,7 +2444,6 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen) nt_devmode->panningheight, nt_devmode->nt_dev_private); - if (nt_devmode->nt_dev_private) { len += tdb_pack(buf+len, buflen-len, "B", nt_devmode->driverextra, @@ -2412,44 +2458,46 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen) /**************************************************************************** Pack all values in all printer keys ***************************************************************************/ - + static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen) { int len = 0; int i, j; REGISTRY_VALUE *val; REGVAL_CTR *val_ctr; - pstring path; + char *path = NULL; int num_values; if ( !data ) return 0; /* loop over all keys */ - - for ( i=0; i<data->num_keys; i++ ) { + + for ( i=0; i<data->num_keys; i++ ) { val_ctr = data->keys[i].values; num_values = regval_ctr_numvals( val_ctr ); /* pack the keyname followed by a empty value */ - len += tdb_pack(buf+len, buflen-len, "pPdB", + len += tdb_pack(buf+len, buflen-len, "pPdB", &data->keys[i].name, - data->keys[i].name, + data->keys[i].name, REG_NONE, 0, NULL); - + /* now loop over all values */ - + for ( j=0; j<num_values; j++ ) { /* pathname should be stored as <key>\<value> */ - + val = regval_ctr_specific_value( val_ctr, j ); - pstrcpy( path, data->keys[i].name ); - pstrcat( path, "\\" ); - pstrcat( path, regval_name(val) ); - + if (asprintf(&path, "%s\\%s", + data->keys[i].name, + regval_name(val)) < 0) { + return -1; + } + len += tdb_pack(buf+len, buflen-len, "pPdB", val, path, @@ -2458,12 +2506,13 @@ static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen) regval_data_p(val) ); DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val))); + SAFE_FREE(path); } - + } /* terminator */ - + len += tdb_pack(buf+len, buflen-len, "p", NULL); return len; @@ -2478,22 +2527,25 @@ static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen) uint32 del_a_printer(const char *sharename) { TDB_DATA kbuf; - pstring printdb_path; + char *printdb_path = NULL; + TALLOC_CTX *ctx = talloc_tos(); - kbuf = make_printer_tdbkey( sharename ); + kbuf = make_printer_tdbkey(ctx, sharename); tdb_delete(tdb_printers, kbuf); - kbuf= make_printers_secdesc_tdbkey( sharename ); + kbuf= make_printers_secdesc_tdbkey(ctx, sharename); tdb_delete(tdb_printers, kbuf); close_all_print_db(); if (geteuid() == 0) { - pstrcpy(printdb_path, lock_path("printing/")); - pstrcat(printdb_path, sharename); - pstrcat(printdb_path, ".tdb"); - + if (asprintf(&printdb_path, "%s%s.tdb", + lock_path("printing/"), + sharename) < 0) { + return (uint32)-1; + } unlink(printdb_path); + SAFE_FREE(printdb_path); } return 0; @@ -2505,6 +2557,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) { uint8 *buf; int buflen, len; + int retlen; WERROR ret; TDB_DATA kbuf, dbuf; @@ -2539,7 +2592,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) buf = NULL; buflen = 0; - again: + again: len = 0; len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff", info->attributes, @@ -2566,8 +2619,12 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) info->parameters); len += pack_devicemode(info->devmode, buf+len, buflen-len); - - len += pack_values( info->data, buf+len, buflen-len ); + retlen = pack_values( info->data, buf+len, buflen-len ); + if (retlen == -1) { + ret = WERR_NOMEM; + goto done; + } + len += retlen; if (buflen != len) { buf = (uint8 *)SMB_REALLOC(buf, len); @@ -2579,9 +2636,8 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) buflen = len; goto again; } - - kbuf = make_printer_tdbkey( info->sharename ); + kbuf = make_printer_tdbkey(talloc_tos(), info->sharename ); dbuf.dptr = buf; dbuf.dsize = len; @@ -3645,13 +3701,13 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n", key, value, type, real_len )); - + return result; } /**************************************************************************** ***************************************************************************/ - + REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ) { int key_index; @@ -3668,12 +3724,14 @@ REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, /**************************************************************************** Unpack a list of registry values frem the TDB ***************************************************************************/ - + static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen) { int len = 0; uint32 type; - pstring string, valuename, keyname; + fstring string; + const char *valuename = NULL; + const char *keyname = NULL; char *str; int size; uint8 *data_p; @@ -3681,22 +3739,22 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu int key_index; /* add the "PrinterDriverData" key first for performance reasons */ - + add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY ); /* loop and unpack the rest of the registry values */ - + while ( True ) { - + /* check to see if there are any more registry values */ - + regval_p = NULL; - len += tdb_unpack(buf+len, buflen-len, "p", ®val_p); - if ( !regval_p ) + len += tdb_unpack(buf+len, buflen-len, "p", ®val_p); + if ( !regval_p ) break; /* unpack the next regval */ - + len += tdb_unpack(buf+len, buflen-len, "fdB", string, &type, @@ -3711,64 +3769,64 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu add_new_printer_key( printer_data, string ); continue; } - + /* - * break of the keyname from the value name. + * break of the keyname from the value name. * Valuenames can have embedded '\'s so be careful. - * only support one level of keys. See the + * only support one level of keys. See the * "Konica Fiery S300 50C-K v1.1. enu" 2k driver. * -- jerry - */ - + */ + str = strchr_m( string, '\\'); - + /* Put in "PrinterDriverData" is no key specified */ - + if ( !str ) { - pstrcpy( keyname, SPOOL_PRINTERDATA_KEY ); - pstrcpy( valuename, string ); + keyname = SPOOL_PRINTERDATA_KEY; + valuename = string; } else { *str = '\0'; - pstrcpy( keyname, string ); - pstrcpy( valuename, str+1 ); + keyname = string; + valuename = str+1; } - + /* see if we need a new key */ - + if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 ) key_index = add_new_printer_key( printer_data, keyname ); - + if ( key_index == -1 ) { DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n", keyname)); break; } - + DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size)); - /* Vista doesn't like unknown REG_BINARY values in DsSpooler. + /* Vista doesn't like unknown REG_BINARY values in DsSpooler. Thanks to Martin Zielinski for the hint. */ - if ( type == REG_BINARY && - strequal( keyname, SPOOL_DSSPOOLER_KEY ) && - strequal( valuename, "objectGUID" ) ) + if ( type == REG_BINARY && + strequal( keyname, SPOOL_DSSPOOLER_KEY ) && + strequal( valuename, "objectGUID" ) ) { struct GUID guid; UNISTR2 unistr_guid; ZERO_STRUCT( unistr_guid ); - + /* convert the GUID to a UNICODE string */ - + memcpy( &guid, data_p, sizeof(struct GUID) ); - + init_unistr2( &unistr_guid, smb_uuid_string_static(guid), UNI_STR_TERMINATE ); - + regval_ctr_addvalue( printer_data->keys[key_index].values, - valuename, REG_SZ, - (const char *)unistr_guid.buffer, + valuename, REG_SZ, + (const char *)unistr_guid.buffer, unistr_guid.uni_str_len*2 ); } else { @@ -3778,7 +3836,6 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu valuename, type, (const char *)data_p, size ); } - SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */ @@ -3958,8 +4015,8 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servern TDB_DATA kbuf, dbuf; fstring printername; char adevice[MAXDEVICENAME]; - - kbuf = make_printer_tdbkey( sharename ); + + kbuf = make_printer_tdbkey(talloc_tos(), sharename); dbuf = tdb_fetch(tdb_printers, kbuf); if (!dbuf.dptr) { @@ -4198,14 +4255,13 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level) */ result=update_a_printer_2(printer->info_2); - break; } default: result=WERR_UNKNOWN_LEVEL; break; } - + return result; } @@ -4216,7 +4272,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level) static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) { int len = 0; - pstring key; + char *key = NULL; TDB_DATA dbuf; NT_PRINTER_INFO_LEVEL_2 info; @@ -4228,11 +4284,14 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) * replace, there will generally be some, but during an add printer, there * should not be any (if there are delete them). */ - + if ( info_ptr->data ) delete_all_printer_data( info_ptr, "" ); - - slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername); + + if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, + info_ptr->drivername) < 0) { + return false; + } dbuf = tdb_fetch_bystring(tdb_drivers, key); if (!dbuf.dptr) { @@ -4241,20 +4300,22 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) * the previous drivers init info and leave the new on blank. */ free_nt_devicemode(&info_ptr->devmode); - return False; + SAFE_FREE(key); + return false; } - + + SAFE_FREE(key); /* * Get the saved DEVMODE.. */ - + len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len); /* * The saved DEVMODE contains the devicename from the printer used during * the initialization save. Change it to reflect the new printer. */ - + if ( info.devmode ) { ZERO_STRUCT(info.devmode->devicename); fstrcpy(info.devmode->devicename, info_ptr->printername); @@ -4262,18 +4323,18 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) /* * NT/2k does not change out the entire DeviceMode of a printer - * when changing the driver. Only the driverextra, private, & + * when changing the driver. Only the driverextra, private, & * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002) * * Later examination revealed that Windows NT/2k does reset the - * the printer's device mode, bit **only** when you change a + * the printer's device mode, bit **only** when you change a * property of the device mode such as the page orientation. * --jerry */ /* Bind the saved DEVMODE to the new the printer */ - + free_nt_devicemode(&info_ptr->devmode); info_ptr->devmode = info.devmode; @@ -4286,13 +4347,12 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) DEBUG(0,("set_driver_init_2: talloc() failed!\n")); return False; } - + len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len ); - SAFE_FREE(dbuf.dptr); - return True; + return true; } /**************************************************************************** @@ -4305,18 +4365,18 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) { bool result = False; - + switch (level) { case 2: result = set_driver_init_2(printer->info_2); break; - + default: DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n", level)); break; } - + return result; } @@ -4326,18 +4386,24 @@ bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) bool del_driver_init(char *drivername) { - pstring key; + char *key; + bool ret; if (!drivername || !*drivername) { DEBUG(3,("del_driver_init: No drivername specified!\n")); - return False; + return false; } - slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, drivername); + if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, drivername) < 0) { + return false; + } - DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername)); + DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", + drivername)); - return (tdb_delete_bystring(tdb_drivers, key) == 0); + ret = (tdb_delete_bystring(tdb_drivers, key) == 0); + SAFE_FREE(key); + return ret; } /**************************************************************************** @@ -4350,19 +4416,25 @@ bool del_driver_init(char *drivername) static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info) { - pstring key; + char *key = NULL; uint8 *buf; int buflen, len, ret; + int retlen; TDB_DATA dbuf; buf = NULL; buflen = 0; - again: + again: len = 0; len += pack_devicemode(info->devmode, buf+len, buflen-len); - len += pack_values( info->data, buf+len, buflen-len ); + retlen = pack_values( info->data, buf+len, buflen-len ); + if (retlen == -1) { + ret = -1; + goto done; + } + len += retlen; if (buflen < len) { buf = (uint8 *)SMB_REALLOC(buf, len); @@ -4375,7 +4447,11 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info) goto again; } - slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername); + SAFE_FREE(key); + if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, info->drivername) < 0) { + ret = (uint32)-1; + goto done; + } dbuf.dptr = buf; dbuf.dsize = len; @@ -5007,25 +5083,25 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) return True; } } - + free_a_printer_driver(driver, 3); - } - + } + SAFE_FREE(list); - + DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n")); - + driver.info_3 = info; - + if ( DEBUGLEVEL >= 20 ) dump_a_printer_driver( driver, 3 ); - + return False; } /**************************************************************************** - Actually delete the driver files. Make sure that - printer_driver_files_in_use() return False before calling + Actually delete the driver files. Make sure that + printer_driver_files_in_use() return False before calling this. ****************************************************************************/ @@ -5033,7 +5109,7 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct { int i = 0; char *s; - pstring file; + const char *file; connection_struct *conn; DATA_BLOB null_pw; NTSTATUS nt_status; @@ -5042,21 +5118,21 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct if ( !info_3 ) return False; - + DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion)); - + /* - * Connect to the print$ share under the same account as the - * user connected to the rpc pipe. Note we must be root to + * Connect to the print$ share under the same account as the + * user connected to the rpc pipe. Note we must be root to * do this. */ - + null_pw = data_blob_null; fstrcpy(res_type, "A:"); become_root(); conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status ); unbecome_root(); - + if ( !conn ) { DEBUG(0,("delete_driver_files: Unable to connect\n")); return False; @@ -5074,67 +5150,67 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct return False; } - /* now delete the files; must strip the '\print$' string from + /* now delete the files; must strip the '\print$' string from fron of path */ - + if ( *info_3->driverpath ) { if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) { - pstrcpy( file, s ); + file = s; driver_unix_convert(conn,file,&st); DEBUG(10,("deleting driverfile [%s]\n", s)); unlink_internals(conn, NULL, 0, file, False); } } - + if ( *info_3->configfile ) { if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) { - pstrcpy( file, s ); + file = s; driver_unix_convert(conn,file,&st); DEBUG(10,("deleting configfile [%s]\n", s)); unlink_internals(conn, NULL, 0, file, False); } } - + if ( *info_3->datafile ) { if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) { - pstrcpy( file, s ); + file = s; driver_unix_convert(conn,file,&st); DEBUG(10,("deleting datafile [%s]\n", s)); unlink_internals(conn, NULL, 0, file, False); } } - + if ( *info_3->helpfile ) { if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) { - pstrcpy( file, s ); + file = s; driver_unix_convert(conn,file,&st); DEBUG(10,("deleting helpfile [%s]\n", s)); unlink_internals(conn, NULL, 0, file, False); } } - + /* check if we are done removing files */ - + if ( info_3->dependentfiles ) { while ( info_3->dependentfiles[i][0] ) { char *p; /* bypass the "\print$" portion of the path */ - + if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) { - pstrcpy( file, p ); + file = p; driver_unix_convert(conn,file,&st); DEBUG(10,("deleting dependent file [%s]\n", file)); unlink_internals(conn, NULL, 0, file, False); } - + i++; } } unbecome_user(); - - return True; + + return true; } /**************************************************************************** @@ -5145,7 +5221,7 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user, uint32 version, bool delete_files ) { - pstring key; + char *key = NULL; const char *arch; TDB_DATA dbuf; NT_PRINTER_DRIVER_INFO_LEVEL ctr; @@ -5156,8 +5232,10 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur if (!arch) { return WERR_UNKNOWN_PRINTER_DRIVER; } - slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, - arch, version, info_3->name); + if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX, + arch, version, info_3->name) < 0) { + return WERR_NOMEM; + } DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n", key, delete_files ? "TRUE" : "FALSE" )); @@ -5166,19 +5244,21 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur dump_a_printer_driver( ctr, 3 ); /* check if the driver actually exists for this environment */ - + dbuf = tdb_fetch_bystring( tdb_drivers, key ); if ( !dbuf.dptr ) { DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key)); + SAFE_FREE(key); return WERR_UNKNOWN_PRINTER_DRIVER; } - + SAFE_FREE( dbuf.dptr ); - + /* ok... the driver exists so the delete should return success */ - + if (tdb_delete_bystring(tdb_drivers, key) == -1) { DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key)); + SAFE_FREE(key); return WERR_ACCESS_DENIED; } @@ -5190,13 +5270,13 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur if ( delete_files ) delete_driver_files( info_3, user ); - - + DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key)); + SAFE_FREE(key); return WERR_OK; - } - +} + /**************************************************************************** Store a security desc for a printer. ****************************************************************************/ @@ -5279,7 +5359,7 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) goto out; } - kbuf = make_printers_secdesc_tdbkey( sharename ); + kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename ); if (tdb_prs_store(tdb_printers, kbuf, &ps)==0) { status = WERR_OK; @@ -5400,7 +5480,7 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s /* Fetch security descriptor from tdb */ - kbuf = make_printers_secdesc_tdbkey( sharename ); + kbuf = make_printers_secdesc_tdbkey(ctx, sharename ); if (tdb_prs_fetch(tdb_printers, kbuf, &ps, ctx)!=0 || !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) { diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index aabdb73e2e..30cb254a29 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -159,8 +159,9 @@ void pcap_cache_reload(void) goto done; } - for (; (pcap_line = fgets_slash(NULL, sizeof(pstring), pcap_file)) != NULL; safe_free(pcap_line)) { - pstring name, comment; + for (; (pcap_line = fgets_slash(NULL, 1024, pcap_file)) != NULL; safe_free(pcap_line)) { + char name[MAXPRINTERLEN+1]; + char comment[62]; char *p, *q; if (*pcap_line == '#' || *pcap_line == 0) @@ -186,22 +187,22 @@ void pcap_cache_reload(void) strchr_m(p, ')')); if (strlen(p) > strlen(comment) && has_punctuation) { - pstrcpy(comment, p); + strlcpy(comment, p, sizeof(comment)); continue; } if (strlen(p) <= MAXPRINTERLEN && strlen(p) > strlen(name) && !has_punctuation) { - if (!*comment) - pstrcpy(comment, name); - - pstrcpy(name, p); + if (!*comment) { + strlcpy(comment, name, sizeof(comment)); + } + strlcpy(name, p, sizeof(name)); continue; } if (!strchr_m(comment, ' ') && strlen(p) > strlen(comment)) { - pstrcpy(comment, p); + strlcpy(comment, p, sizeof(comment)); continue; } } diff --git a/source3/printing/print_aix.c b/source3/printing/print_aix.c index 15d0740fd2..bb125530df 100644 --- a/source3/printing/print_aix.c +++ b/source3/printing/print_aix.c @@ -32,21 +32,26 @@ bool aix_cache_reload(void) int iEtat; XFILE *pfile; char *line = NULL, *p; - pstring name, comment; + char *name; + TALLOC_CTX *ctx = talloc_init("aix_cache_reload"); + + if (!ctx) { + return false; + } *name = 0; - *comment = 0; DEBUG(5, ("reloading aix printcap cache\n")); if ((pfile = x_fopen(lp_printcapname(), O_RDONLY, 0)) == NULL) { DEBUG(0,( "Unable to open qconfig file %s for read!\n", lp_printcapname())); - return False; + TALLOC_FREE(ctx); + return false; } iEtat = 0; /* scan qconfig file for searching <printername>: */ - for (;(line = fgets_slash(NULL, sizeof(pstring), pfile)); safe_free(line)) { + for (;(line = fgets_slash(NULL, 1024, pfile)); safe_free(line)) { if (*line == '*' || *line == 0) continue; @@ -59,7 +64,13 @@ bool aix_cache_reload(void) *p = '\0'; p = strtok(line, ":"); if (strcmp(p, "bsh") != 0) { - pstrcpy(name, p); + name = talloc_strdup(ctx, p); + if (!name) { + safe_free(line); + x_fclose(pfile); + TALLOC_FREE(ctx); + return false; + } iEtat = 1; continue; } @@ -77,11 +88,12 @@ bool aix_cache_reload(void) if (!pcap_cache_add(name, NULL)) { safe_free(line); x_fclose(pfile); - return False; + TALLOC_FREE(ctx); + return false; } continue; } - + if (strstr_m(line, "backend")) { /* it's a device, not a virtual printer */ iEtat = 0; @@ -91,7 +103,8 @@ bool aix_cache_reload(void) if (!pcap_cache_add(name, NULL)) { safe_free(line); x_fclose(pfile); - return False; + TALLOC_FREE(ctx); + return false; } continue; } @@ -100,7 +113,8 @@ bool aix_cache_reload(void) } x_fclose(pfile); - return True; + TALLOC_FREE(ctx); + return true; } #else diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 2ffd322b45..6e62306d67 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -564,8 +564,8 @@ static int cups_job_submit(int snum, struct printjob *pjob) cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ const char *clientname = NULL; /* hostname of client for job-originating-host attribute */ - pstring new_jobname; - int num_options = 0; + char *new_jobname = NULL; + int num_options = 0; cups_option_t *options = NULL; char addr[INET6_ADDRSTRLEN]; @@ -627,8 +627,10 @@ static int cups_job_submit(int snum, struct printjob *pjob) "job-originating-host-name", NULL, clientname); - pstr_sprintf(new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX, - (unsigned int)pjob->smbjob, pjob->jobname); + if (asprintf(&new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX, + (unsigned int)pjob->smbjob, pjob->jobname) < 0) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, new_jobname); @@ -676,6 +678,8 @@ static int cups_job_submit(int snum, struct printjob *pjob) if (http) httpClose(http); + SAFE_FREE(new_jobname); + return ret; } diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c index 8525d6208b..cc4b744a11 100644 --- a/source3/printing/print_generic.c +++ b/source3/printing/print_generic.c @@ -24,45 +24,63 @@ extern struct current_user current_user; extern userdom_struct current_user_info; /**************************************************************************** -run a given print command -a null terminated list of value/substitute pairs is provided -for local substitution strings + Run a given print command + a null terminated list of value/substitute pairs is provided + for local substitution strings ****************************************************************************/ static int print_run_command(int snum, const char* printername, bool do_sub, const char *command, int *outfd, ...) { - pstring syscmd; + char *syscmd; char *arg; int ret; + TALLOC_CTX *ctx = talloc_tos(); va_list ap; va_start(ap, outfd); /* check for a valid system printername and valid command to run */ - if ( !printername || !*printername ) + if ( !printername || !*printername ) { return -1; + } - if (!command || !*command) + if (!command || !*command) { return -1; + } - pstrcpy(syscmd, command); + syscmd = talloc_strdup(ctx, command); + if (!syscmd) { + return -1; + } while ((arg = va_arg(ap, char *))) { char *value = va_arg(ap,char *); - pstring_sub(syscmd, arg, value); + syscmd = talloc_string_sub(ctx, syscmd, arg, value); + if (!syscmd) { + return -1; + } } va_end(ap); - - pstring_sub( syscmd, "%p", printername ); - - if ( do_sub && snum != -1 ) - standard_sub_advanced(lp_servicename(snum), - current_user_info.unix_name, "", - current_user.ut.gid, - get_current_username(), - current_user_info.domain, - syscmd, sizeof(syscmd)); - + + syscmd = talloc_string_sub(ctx, syscmd, "%p", printername); + if (!syscmd) { + return -1; + } + + if (do_sub && snum != -1) { + syscmd = talloc_sub_advanced(ctx, + lp_servicename(snum), + current_user_info.unix_name, + "", + current_user.ut.gid, + get_current_username(), + current_user_info.domain, + syscmd); + if (!syscmd) { + return -1; + } + } + ret = smbrun_no_sanitize(syscmd,outfd); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -107,7 +125,7 @@ resume a job static int generic_job_resume(int snum, struct printjob *pjob) { fstring jobstr; - + /* need to pause the spooled entry */ slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); return print_run_command(snum, PRINTERNAME(snum), True, @@ -122,30 +140,52 @@ static int generic_job_resume(int snum, struct printjob *pjob) static int generic_job_submit(int snum, struct printjob *pjob) { - int ret; - pstring current_directory; - pstring print_directory; - char *wd, *p; - pstring jobname; + int ret = -1; + char *current_directory = NULL; + char *print_directory = NULL; + char *wd = NULL; + char *p = NULL; + char *jobname = NULL; + TALLOC_CTX *ctx = talloc_tos(); fstring job_page_count, job_size; /* we print from the directory path to give the best chance of parsing the lpq output */ + current_directory = TALLOC_ARRAY(ctx, + char, + PATH_MAX+1); + if (!current_directory) { + return -1; + } wd = sys_getwd(current_directory); - if (!wd) - return 0; + if (!wd) { + return -1; + } - pstrcpy(print_directory, pjob->filename); + print_directory = talloc_strdup(ctx, pjob->filename); + if (!print_directory) { + return -1; + } p = strrchr_m(print_directory,'/'); - if (!p) - return 0; + if (!p) { + return -1; + } *p++ = 0; - if (chdir(print_directory) != 0) - return 0; + if (chdir(print_directory) != 0) { + return -1; + } - pstrcpy(jobname, pjob->jobname); - pstring_sub(jobname, "'", "_"); + jobname = talloc_strdup(ctx, pjob->jobname); + if (!jobname) { + ret = -1; + goto out; + } + jobname = talloc_string_sub(ctx, jobname, "'", "_"); + if (!jobname) { + ret = -1; + goto out; + } slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count); slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size); @@ -159,8 +199,10 @@ static int generic_job_submit(int snum, struct printjob *pjob) "%c", job_page_count, NULL); - chdir(wd); + out: + chdir(wd); + TALLOC_FREE(current_directory); return ret; } diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 48ac54d797..d331e897f9 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1475,7 +1475,6 @@ static void print_queue_update(int snum, bool force) return; } - pstrcpy( lprmcommand, lp_lprmcommand(snum)); lprmcommand = talloc_string_sub2(ctx, lp_lprmcommand(snum), "%p", diff --git a/source3/printing/printing_db.c b/source3/printing/printing_db.c index db736765fc..94319f96d0 100644 --- a/source3/printing/printing_db.c +++ b/source3/printing/printing_db.c @@ -33,7 +33,7 @@ struct tdb_print_db *get_print_db_byname(const char *printername) { struct tdb_print_db *p = NULL, *last_entry = NULL; int num_open = 0; - pstring printdb_path; + char *printdb_path = NULL; bool done_become_root = False; SMB_ASSERT(printername != NULL); @@ -78,7 +78,7 @@ struct tdb_print_db *get_print_db_byname(const char *printername) p = print_db_head; } } - + if (!p) { /* Create one. */ p = SMB_MALLOC_P(struct tdb_print_db); @@ -90,9 +90,13 @@ struct tdb_print_db *get_print_db_byname(const char *printername) DLIST_ADD(print_db_head, p); } - pstrcpy(printdb_path, lock_path("printing/")); - pstrcat(printdb_path, printername); - pstrcat(printdb_path, ".tdb"); + if (asprintf(&printdb_path, "%s%s.tdb", + lock_path("printing/"), + printername) < 0) { + DLIST_REMOVE(print_db_head, p); + SAFE_FREE(p); + return NULL; + } if (geteuid() != 0) { become_root(); @@ -109,9 +113,11 @@ struct tdb_print_db *get_print_db_byname(const char *printername) DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n", printdb_path )); DLIST_REMOVE(print_db_head, p); + SAFE_FREE(printdb_path); SAFE_FREE(p); return NULL; } + SAFE_FREE(printdb_path); fstrcpy(p->printer_name, printername); p->ref_count++; return p; diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index a92031daaa..7e3ce04d6c 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -1374,7 +1374,6 @@ done: bool fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid) { - extern pstring global_myname; struct cli_state cli; NTSTATUS result; POLICY_HND lsa_pol; @@ -1397,7 +1396,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); goto done; } - if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) { + if (!attempt_netbios_session_request(&cli, global_myname(), remote_machine, &cli.dest_ip)) { DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n", remote_machine)); goto done; diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1e5e04448f..c93e26ccbc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1551,13 +1551,15 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE); prs_mem_free(&outgoing_pdu); - if (DEBUGLEVEL >= 50) { - pstring dump_name; + char *dump_name = NULL; /* Also capture received data */ - slprintf(dump_name, sizeof(dump_name) - 1, "%s/reply_%s_%d", - dyn_LOGFILEBASE, cli->pipe_name, op_num); - prs_dump(dump_name, op_num, out_data); + if (asprintf(&dump_name, "%s/reply_%s_%d", + dyn_LOGFILEBASE, cli->pipe_name, + op_num) > 0) { + prs_dump(dump_name, op_num, out_data); + SAFE_FREE(dump_name); + } } return ret; diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index e12d9dda0d..df11c6d75a 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -1086,7 +1086,7 @@ bool net_io_r_srv_pwset(const char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, static int init_dom_sid2s(TALLOC_CTX *ctx, const char *sids_str, DOM_SID2 **ppsids) { const char *ptr; - pstring s2; + fstring s2; int count = 0; DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:"")); diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index a30e96772a..4abf63e71d 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -28,7 +28,7 @@ /** * Dump a prs to a file: from the current location through to the end. **/ -void prs_dump(char *name, int v, prs_struct *ps) +void prs_dump(const char *name, int v, prs_struct *ps) { prs_dump_region(name, v, ps, ps->data_offset, ps->buffer_size); } @@ -36,7 +36,7 @@ void prs_dump(char *name, int v, prs_struct *ps) /** * Dump from the start of the prs to the current location. **/ -void prs_dump_before(char *name, int v, prs_struct *ps) +void prs_dump_before(const char *name, int v, prs_struct *ps) { prs_dump_region(name, v, ps, 0, ps->data_offset); } @@ -44,18 +44,22 @@ void prs_dump_before(char *name, int v, prs_struct *ps) /** * Dump everything from the start of the prs up to the current location. **/ -void prs_dump_region(char *name, int v, prs_struct *ps, +void prs_dump_region(const char *name, int v, prs_struct *ps, int from_off, int to_off) { int fd, i; - pstring fname; + char *fname = NULL; ssize_t sz; if (DEBUGLEVEL < 50) return; for (i=1;i<100;i++) { if (v != -1) { - slprintf(fname,sizeof(fname)-1, "/tmp/%s_%d.%d.prs", name, v, i); + if (asprintf(&fname,"/tmp/%s_%d.%d.prs", name, v, i) < 0) { + return; + } } else { - slprintf(fname,sizeof(fname)-1, "/tmp/%s.%d.prs", name, i); + if (asprintf(&fname,"/tmp/%s.%d.prs", name, i) < 0) { + return; + } } fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644); if (fd != -1 || errno != EEXIST) break; @@ -69,6 +73,7 @@ void prs_dump_region(char *name, int v, prs_struct *ps, DEBUG(0,("created %s\n", fname)); } } + SAFE_FREE(fname); } /******************************************************************* diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index e573e92648..3bcf1bdcc9 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -675,17 +675,20 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, static void display_reg_value(REGISTRY_VALUE value) { - pstring text; + char *text = NULL; switch(value.type) { case REG_DWORD: - printf("%s: REG_DWORD: 0x%08x\n", value.valuename, + printf("%s: REG_DWORD: 0x%08x\n", value.valuename, *((uint32 *) value.data_p)); break; case REG_SZ: - rpcstr_pull(text, value.data_p, sizeof(text), value.size, - STR_TERMINATE); - printf("%s: REG_SZ: %s\n", value.valuename, text); + rpcstr_pull_talloc(talloc_tos(), + &text, + value.data_p, + value.size, + STR_TERMINATE); + printf("%s: REG_SZ: %s\n", value.valuename, text ? text : ""); break; case REG_BINARY: { char *hex = hex_encode(NULL, value.data_p, value.size); @@ -2163,16 +2166,16 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, WERROR result; uint32 level = 1, num_jobs, i; bool got_hnd = False; - pstring printername; + char *printername = NULL; fstring servername, user; POLICY_HND hnd; JOB_INFO_CTR ctr; - + if (argc < 2 || argc > 3) { printf("Usage: %s printername [level]\n", argv[0]); return WERR_OK; } - + if (argc == 3) level = atoi(argv[2]); @@ -2181,17 +2184,25 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost); strupper_m(servername); fstrcpy(user, cli->user_name); - slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->cli->desthost); + printername = talloc_asprintf(mem_ctx, + "\\\\%s\\", + cli->cli->desthost); + if (!printername) { + return WERR_NOMEM; + } strupper_m(printername); - pstrcat(printername, argv[1]); + printername = talloc_asprintf_append(printername, "%s", argv[1]); + if (!printername) { + return WERR_NOMEM; + } - result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, - "", MAXIMUM_ALLOWED_ACCESS, + result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, + "", MAXIMUM_ALLOWED_ACCESS, servername, user, &hnd); if (!W_ERROR_IS_OK(result)) goto done; - + got_hnd = True; /* Enumerate ports */ @@ -2233,7 +2244,7 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, WERROR result; uint32 i=0, val_needed, data_needed; bool got_hnd = False; - pstring printername; + char *printername = NULL; fstring servername, user; POLICY_HND hnd; @@ -2241,18 +2252,28 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, printf("Usage: %s printername\n", argv[0]); return WERR_OK; } - + /* Open printer handle */ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost); strupper_m(servername); fstrcpy(user, cli->user_name); - slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost); + printername = talloc_asprintf(mem_ctx, + "\\\\%s\\", + cli->cli->desthost); + if (!printername) { + return WERR_NOMEM; + } strupper_m(printername); - pstrcat(printername, argv[1]); + printername = talloc_asprintf_append(mem_ctx, + "%s", + argv[1]); + if (!printername) { + return WERR_NOMEM; + } - result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, - "", MAXIMUM_ALLOWED_ACCESS, + result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, + "", MAXIMUM_ALLOWED_ACCESS, servername, user, &hnd); if (!W_ERROR_IS_OK(result)) @@ -2293,7 +2314,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, WERROR result; uint32 i; bool got_hnd = False; - pstring printername; + char *printername = NULL; fstring servername, user; const char *keyname = NULL; POLICY_HND hnd; @@ -2303,7 +2324,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, printf("Usage: %s printername <keyname>\n", argv[0]); return WERR_OK; } - + keyname = argv[2]; /* Open printer handle */ @@ -2311,9 +2332,20 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost); strupper_m(servername); fstrcpy(user, cli->user_name); - slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost); + + printername = talloc_asprintf(mem_ctx, + "\\\\%s\\", + cli->cli->desthost); + if (!printername) { + return WERR_NOMEM; + } strupper_m(printername); - pstrcat(printername, argv[1]); + printername = talloc_asprintf_append(mem_ctx, + "%s", + argv[1]); + if (!printername) { + return WERR_NOMEM; + } result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, @@ -2356,7 +2388,7 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, { WERROR result; bool got_hnd = False; - pstring printername; + char *printername = NULL; fstring servername, user; const char *keyname = NULL; POLICY_HND hnd; @@ -2366,7 +2398,7 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, printf("Usage: %s printername [keyname]\n", argv[0]); return WERR_OK; } - + if (argc == 3) keyname = argv[2]; else @@ -2377,9 +2409,21 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost); strupper_m(servername); fstrcpy(user, cli->user_name); - slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost); + + printername = talloc_asprintf(mem_ctx, + "\\\\%s\\", + cli->cli->desthost); + if (!printername) { + return WERR_NOMEM; + } strupper_m(printername); - pstrcat(printername, argv[1]); + printername = talloc_asprintf_append(mem_ctx, + "%s", + argv[1]); + if (!printername) { + return WERR_NOMEM; + } + result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, @@ -2399,9 +2443,12 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, curkey = keylist; while (*curkey != 0) { - pstring subkey; - rpcstr_pull(subkey, curkey, sizeof(subkey), -1, + char *subkey = NULL; + rpcstr_pull_talloc(mem_ctx, &subkey, curkey, -1, STR_TERMINATE); + if (!subkey) { + break; + } printf("%s\n", subkey); curkey += strlen(subkey) + 1; } @@ -2605,38 +2652,37 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, const char **argv) { fstring printername, servername1, servername2; - pstring printername_path; + char *printername_path = NULL; struct cli_state *cli_server1 = cli->cli; struct cli_state *cli_server2 = NULL; struct rpc_pipe_client *cli2 = NULL; POLICY_HND hPrinter1, hPrinter2; NTSTATUS nt_status; WERROR werror; - + if ( argc != 3 ) { printf("Usage: %s <printer> <server>\n", argv[0]); return WERR_OK; } - + fstrcpy( printername, argv[1] ); - + fstr_sprintf( servername1, cli->cli->desthost ); fstrcpy( servername2, argv[2] ); strupper_m( servername1 ); strupper_m( servername2 ); - - + /* first get the connection to the remote server */ - + nt_status = cli_full_connection(&cli_server2, global_myname(), servername2, NULL, 0, - "IPC$", "IPC", - cmdline_auth_info.username, + "IPC$", "IPC", + cmdline_auth_info.username, lp_workgroup(), - cmdline_auth_info.password, + cmdline_auth_info.password, cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0, cmdline_auth_info.signing_state, NULL); - + if ( !NT_STATUS_IS_OK(nt_status) ) return WERR_GENERAL_FAILURE; @@ -2646,10 +2692,16 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, servername2, nt_errstr(nt_status)); return WERR_GENERAL_FAILURE; } - + /* now open up both printers */ - pstr_sprintf( printername_path, "\\\\%s\\%s", servername1, printername ); + printername_path = talloc_asprintf(mem_ctx, + "\\\\%s\\%s", + servername1, + printername); + if (!printername_path) { + return WERR_NOMEM; + } printf("Opening %s...", printername_path); werror = rpccli_spoolss_open_printer_ex( cli, mem_ctx, printername_path, "", PRINTER_ALL_ACCESS, servername1, cli_server1->user_name, &hPrinter1); @@ -2658,8 +2710,14 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, goto done; } printf("ok\n"); - - pstr_sprintf( printername_path, "\\\\%s\\%s", servername2, printername ); + + printername_path = talloc_asprintf(mem_ctx, + "\\\\%s\\%s", + servername2, + printername); + if (!printername_path) { + return WERR_NOMEM; + } printf("Opening %s...", printername_path); werror = rpccli_spoolss_open_printer_ex( cli2, mem_ctx, printername_path, "", PRINTER_ALL_ACCESS, servername2, cli_server2->user_name, &hPrinter2 ); @@ -2668,8 +2726,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, goto done; } printf("ok\n"); - - + compare_printer( cli, &hPrinter1, cli2, &hPrinter2 ); compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 ); #if 0 @@ -2680,15 +2737,14 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, done: /* cleanup */ - printf("Closing printers..."); + printf("Closing printers..."); rpccli_spoolss_close_printer( cli, mem_ctx, &hPrinter1 ); rpccli_spoolss_close_printer( cli2, mem_ctx, &hPrinter2 ); printf("ok\n"); - + /* close the second remote connection */ - + cli_shutdown( cli_server2 ); - return WERR_OK; } diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 6d318ae7ec..9f59ea6f8c 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -878,12 +878,9 @@ out_free: /* Loop around accepting commands */ while(1) { - pstring prompt; char *line; - slprintf(prompt, sizeof(prompt) - 1, "rpcclient $> "); - - line = smb_readline(prompt, NULL, completion_fn); + line = smb_readline("rpcclient $> ", NULL, completion_fn); if (line == NULL) break; diff --git a/source3/services/services_db.c b/source3/services/services_db.c index ccb69d76e4..07f7aa6002 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -33,7 +33,7 @@ struct service_display_info { const char *description; }; -struct service_display_info builtin_svcs[] = { +struct service_display_info builtin_svcs[] = { { "Spooler", "smbd", "Print Spooler", "Internal service for spooling files to print devices" }, { "NETLOGON", "smbd", "Net Logon", "File service providing access to policy and profile data (not remotely manageable)" }, { "RemoteRegistry", "smbd", "Remote Registry Service", "Internal service providing remote access to " @@ -43,7 +43,7 @@ struct service_display_info builtin_svcs[] = { { NULL, NULL, NULL, NULL } }; -struct service_display_info common_unix_svcs[] = { +struct service_display_info common_unix_svcs[] = { { "cups", NULL, "Common Unix Printing System","Provides unified printing support for all operating systems" }, { "postfix", NULL, "Internet Mail Service", "Provides support for sending and receiving electonic mail" }, { "sendmail", NULL, "Internet Mail Service", "Provides support for sending and receiving electonic mail" }, @@ -88,27 +88,27 @@ struct service_display_info common_unix_svcs[] = { static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx ) { - SEC_ACE ace[4]; + SEC_ACE ace[4]; SEC_ACCESS mask; size_t i = 0; SEC_DESC *sd; SEC_ACL *acl; size_t sd_size; - + /* basic access for Everyone */ - + init_sec_access(&mask, SERVICE_READ_ACCESS ); init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - + init_sec_access(&mask,SERVICE_EXECUTE_ACCESS ); init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - + init_sec_access(&mask,SERVICE_ALL_ACCESS ); init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - + /* create the security descriptor */ - + if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) return NULL; @@ -127,52 +127,58 @@ static char *get_common_service_dispname( const char *servicename ) { static fstring dispname; int i; - + for ( i=0; common_unix_svcs[i].servicename; i++ ) { - if ( strequal( servicename, common_unix_svcs[i].servicename ) ) { - fstr_sprintf( dispname, "%s (%s)", + if (strequal(servicename, common_unix_svcs[i].servicename)) { + fstr_sprintf( dispname, "%s (%s)", common_unix_svcs[i].dispname, common_unix_svcs[i].servicename ); - + return dispname; } - } - + } + fstrcpy( dispname, servicename ); - + return dispname; } /******************************************************************** ********************************************************************/ -static char* cleanup_string( const char *string ) +static char *cleanup_string( const char *string ) { - pstring clean; + char *clean = NULL; char *begin, *end; + TALLOC_CTX *ctx = talloc_tos(); - pstrcpy( clean, string ); + clean = talloc_strdup(ctx, string); + if (!clean) { + return NULL; + } begin = clean; - + /* trim any beginning whilespace */ - - while ( isspace(*begin) ) + + while (isspace(*begin)) { begin++; + } - if ( *begin == '\0' ) + if (*begin == '\0') { return NULL; - + } + /* trim any trailing whitespace or carriage returns. Start at the end and move backwards */ - + end = begin + strlen(begin) - 1; - + while ( isspace(*end) || *end=='\n' || *end=='\r' ) { *end = '\0'; end--; } - return talloc_strdup(talloc_tos(), begin); + return begin; } /******************************************************************** @@ -181,50 +187,57 @@ static char* cleanup_string( const char *string ) static bool read_init_file( const char *servicename, struct rcinit_file_information **service_info ) { struct rcinit_file_information *info; - pstring filepath, str; + char *filepath = NULL; + char str[1024]; XFILE *f; char *p; - + if ( !(info = TALLOC_ZERO_P( NULL, struct rcinit_file_information ) ) ) return False; - + /* attempt the file open */ - - pstr_sprintf( filepath, "%s/%s/%s", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, servicename ); - if ( !(f = x_fopen( filepath, O_RDONLY, 0 )) ) { + + filepath = talloc_asprintf(info, "%s/%s/%s", dyn_LIBDIR, + SVCCTL_SCRIPT_DIR, servicename); + if (!filepath) { + TALLOC_FREE(info); + return false; + } + if (!(f = x_fopen( filepath, O_RDONLY, 0 ))) { DEBUG(0,("read_init_file: failed to open [%s]\n", filepath)); TALLOC_FREE(info); - return False; + return false; } - + while ( (x_fgets( str, sizeof(str)-1, f )) != NULL ) { - /* ignore everything that is not a full line + /* ignore everything that is not a full line comment starting with a '#' */ - + if ( str[0] != '#' ) continue; - + /* Look for a line like '^#.*Description:' */ - + if ( (p = strstr( str, "Description:" )) != NULL ) { char *desc; p += strlen( "Description:" ) + 1; - if ( !p ) + if ( !p ) break; - + if ( (desc = cleanup_string(p)) != NULL ) info->description = talloc_strdup( info, desc ); } } - + x_fclose( f ); - + if ( !info->description ) info->description = talloc_strdup( info, "External Unix Service" ); - + *service_info = info; - + TALLOC_FREE(filepath); + return True; } @@ -237,50 +250,62 @@ static void fill_service_values( const char *name, REGVAL_CTR *values ) { UNISTR2 data, dname, ipath, description; uint32 dword; - pstring pstr; int i; - + /* These values are hardcoded in all QueryServiceConfig() replies. I'm just storing them here for cosmetic purposes */ - + dword = SVCCTL_AUTO_START; regval_ctr_addvalue( values, "Start", REG_DWORD, (char*)&dword, sizeof(uint32)); - + dword = SVCCTL_WIN32_OWN_PROC; regval_ctr_addvalue( values, "Type", REG_DWORD, (char*)&dword, sizeof(uint32)); dword = SVCCTL_SVC_ERROR_NORMAL; regval_ctr_addvalue( values, "ErrorControl", REG_DWORD, (char*)&dword, sizeof(uint32)); - + /* everything runs as LocalSystem */ - + init_unistr2( &data, "LocalSystem", UNI_STR_TERMINATE ); regval_ctr_addvalue( values, "ObjectName", REG_SZ, (char*)data.buffer, data.uni_str_len*2); - + /* special considerations for internal services and the DisplayName value */ - + for ( i=0; builtin_svcs[i].servicename; i++ ) { if ( strequal( name, builtin_svcs[i].servicename ) ) { - pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, builtin_svcs[i].daemon ); - init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); + char *pstr = NULL; + if (asprintf(&pstr, "%s/%s/%s", + dyn_LIBDIR, SVCCTL_SCRIPT_DIR, + builtin_svcs[i].daemon) > 0) { + init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); + SAFE_FREE(pstr); + } else { + init_unistr2( &ipath, "", UNI_STR_TERMINATE ); + } init_unistr2( &description, builtin_svcs[i].description, UNI_STR_TERMINATE ); init_unistr2( &dname, builtin_svcs[i].dispname, UNI_STR_TERMINATE ); break; } - } - + } + /* default to an external service if we haven't found a match */ - + if ( builtin_svcs[i].servicename == NULL ) { + char *pstr = NULL; struct rcinit_file_information *init_info = NULL; - pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, name ); - init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); - + if (asprintf(&pstr, "%s/%s/%s",dyn_LIBDIR, + SVCCTL_SCRIPT_DIR, name) > 0) { + init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); + SAFE_FREE(pstr); + } else { + init_unistr2( &ipath, "", UNI_STR_TERMINATE ); + } + /* lookup common unix display names */ init_unistr2( &dname, get_common_service_dispname( name ), UNI_STR_TERMINATE ); - /* get info from init file itself */ + /* get info from init file itself */ if ( read_init_file( name, &init_info ) ) { init_unistr2( &description, init_info->description, UNI_STR_TERMINATE ); TALLOC_FREE( init_info ); @@ -289,25 +314,25 @@ static void fill_service_values( const char *name, REGVAL_CTR *values ) init_unistr2( &description, "External Unix Service", UNI_STR_TERMINATE ); } } - + /* add the new values */ - + regval_ctr_addvalue( values, "DisplayName", REG_SZ, (char*)dname.buffer, dname.uni_str_len*2); regval_ctr_addvalue( values, "ImagePath", REG_SZ, (char*)ipath.buffer, ipath.uni_str_len*2); regval_ctr_addvalue( values, "Description", REG_SZ, (char*)description.buffer, description.uni_str_len*2); - + return; } /******************************************************************** ********************************************************************/ -static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, +static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, const char *name ) { REGISTRY_KEY *key_service, *key_secdesc; WERROR wresult; - pstring path; + char *path = NULL; REGVAL_CTR *values; REGSUBKEY_CTR *svc_subkeys; SEC_DESC *sd; @@ -321,15 +346,19 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* open the new service key */ - pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); + if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) { + return; + } wresult = regkey_open_internal( NULL, &key_service, path, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { - DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", + DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + SAFE_FREE(path); return; } - + SAFE_FREE(path); + /* add the 'Security' key */ if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) { @@ -337,13 +366,13 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, TALLOC_FREE( key_service ); return; } - + fetch_reg_keys( key_service, svc_subkeys ); regsubkey_ctr_addkey( svc_subkeys, "Security" ); store_reg_keys( key_service, svc_subkeys ); /* now for the service values */ - + if ( !(values = TALLOC_ZERO_P( key_service, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); TALLOC_FREE( key_service ); @@ -359,15 +388,19 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* now add the security descriptor */ - pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" ); + if (asprintf(&path, "%s\\%s\\%s", KEY_SERVICES, name, "Security") < 0) { + return; + } wresult = regkey_open_internal( NULL, &key_secdesc, path, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { - DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", + DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); TALLOC_FREE( key_secdesc ); + SAFE_FREE(path); return; } + SAFE_FREE(path); if ( !(values = TALLOC_ZERO_P( key_secdesc, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); @@ -389,11 +422,11 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, TALLOC_FREE(key_secdesc); return; } - + regval_ctr_addvalue(values, "Security", REG_BINARY, (const char *)sd_blob.data, sd_blob.length); store_reg_values( key_secdesc, values ); - + TALLOC_FREE( key_secdesc ); return; @@ -409,35 +442,35 @@ void svcctl_init_keys( void ) REGSUBKEY_CTR *subkeys; REGISTRY_KEY *key = NULL; WERROR wresult; - + /* bad mojo here if the lookup failed. Should not happen */ - + wresult = regkey_open_internal( NULL, &key, KEY_SERVICES, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { - DEBUG(0,("svcctl_init_keys: key lookup failed! (%s)\n", + DEBUG(0,("svcctl_init_keys: key lookup failed! (%s)\n", dos_errstr(wresult))); return; } - - /* lookup the available subkeys */ - + + /* lookup the available subkeys */ + if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) { DEBUG(0,("svcctl_init_keys: talloc() failed!\n")); TALLOC_FREE( key ); return; } - + fetch_reg_keys( key, subkeys ); - + /* the builting services exist */ - + for ( i=0; builtin_svcs[i].servicename; i++ ) add_new_svc_name( key, subkeys, builtin_svcs[i].servicename ); - + for ( i=0; service_list && service_list[i]; i++ ) { - + /* only add new services */ if ( regsubkey_ctr_key_exists( subkeys, service_list[i] ) ) continue; @@ -458,30 +491,34 @@ void svcctl_init_keys( void ) /******************************************************************** This is where we do the dirty work of filling in things like the - Display name, Description, etc...Always return a default secdesc + Display name, Description, etc...Always return a default secdesc in case of any failure. ********************************************************************/ -SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *token ) +SEC_DESC *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *token ) { REGISTRY_KEY *key; REGVAL_CTR *values; REGISTRY_VALUE *val; SEC_DESC *ret_sd = NULL; - pstring path; + char *path= NULL; WERROR wresult; NTSTATUS status; - + /* now add the security descriptor */ - pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" ); + if (asprintf(&path, "%s\\%s\\%s", KEY_SERVICES, name, "Security") < 0) { + return NULL; + } wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { - DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", + DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + SAFE_FREE(path); return NULL; } + SAFE_FREE(path); if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); @@ -492,13 +529,12 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * fetch_reg_values( key, values ); TALLOC_FREE(key); - + if ( !(val = regval_ctr_getvalue( values, "Security" )) ) { DEBUG(6,("svcctl_get_secdesc: constructing default secdesc for service [%s]\n", name)); return construct_service_sd( ctx ); } - /* stream the service security descriptor */ @@ -520,40 +556,43 @@ bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc, { REGISTRY_KEY *key; WERROR wresult; - pstring path; + char *path = NULL; REGVAL_CTR *values; prs_struct ps; bool ret = False; - + /* now add the security descriptor */ - pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" ); + if (asprintf(&path, "%s\\%s\\%s", KEY_SERVICES, name, "Security") < 0) { + return false; + } wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { - DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", + DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + SAFE_FREE(path); return False; } + SAFE_FREE(path); if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); TALLOC_FREE( key ); return False; } - + /* stream the printer security descriptor */ - prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, key, MARSHALL); - + if ( sec_io_desc("sec_desc", &sec_desc, &ps, 0 ) ) { uint32 offset = prs_offset( &ps ); regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&ps), offset ); ret = store_reg_values( key, values ); } - + /* cleanup */ - + prs_mem_free( &ps ); TALLOC_FREE( key); @@ -563,25 +602,29 @@ bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc, /******************************************************************** ********************************************************************/ -char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) +char *svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) { static fstring display_name; - REGISTRY_KEY *key; + REGISTRY_KEY *key = NULL; REGVAL_CTR *values; REGISTRY_VALUE *val; - pstring path; + char *path = NULL; WERROR wresult; - + /* now add the security descriptor */ - pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); + if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) { + return NULL; + } wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + SAFE_FREE(path); goto fail; } + SAFE_FREE(path); if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n")); @@ -590,14 +633,14 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) } fetch_reg_values( key, values ); - + if ( !(val = regval_ctr_getvalue( values, "DisplayName" )) ) goto fail; rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 ); TALLOC_FREE( key ); - + return display_name; fail: @@ -610,25 +653,29 @@ fail: /******************************************************************** ********************************************************************/ -char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) +char *svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) { static fstring description; - REGISTRY_KEY *key; + REGISTRY_KEY *key = NULL; REGVAL_CTR *values; REGISTRY_VALUE *val; - pstring path; + char *path = NULL; WERROR wresult; - + /* now add the security descriptor */ - pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); + if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) { + return NULL; + } wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + SAFE_FREE(path); return NULL; } + SAFE_FREE(path); if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n")); @@ -637,14 +684,14 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) } fetch_reg_values( key, values ); - + if ( !(val = regval_ctr_getvalue( values, "Description" )) ) fstrcpy( description, "Unix Service"); else rpcstr_pull( description, regval_data_p(val), sizeof(description), regval_size(val), 0 ); TALLOC_FREE( key ); - + return description; } @@ -652,34 +699,35 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) /******************************************************************** ********************************************************************/ -REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ) +REGVAL_CTR *svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ) { - REGISTRY_KEY *key; + REGISTRY_KEY *key = NULL; REGVAL_CTR *values; - pstring path; + char *path = NULL; WERROR wresult; - + /* now add the security descriptor */ - pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); + if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) { + return NULL; + } wresult = regkey_open_internal( NULL, &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { - DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n", + DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + SAFE_FREE(path); return NULL; } + SAFE_FREE(path); if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) { DEBUG(0,("svcctl_fetch_regvalues: talloc() failed!\n")); TALLOC_FREE( key ); return NULL; } - fetch_reg_values( key, values ); TALLOC_FREE( key ); - return values; } - diff --git a/source3/services/svc_rcinit.c b/source3/services/svc_rcinit.c index f65015b059..66f89f2248 100644 --- a/source3/services/svc_rcinit.c +++ b/source3/services/svc_rcinit.c @@ -24,20 +24,25 @@ static WERROR rcinit_stop( const char *service, SERVICE_STATUS *status ) { - pstring command; + char *command = NULL; int ret, fd; - - pstr_sprintf( command, "%s/%s/%s stop", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service ); - + + if (asprintf(&command, "%s/%s/%s stop", + dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service) < 0) { + return WERR_NOMEM; + } + /* we've already performed the access check when the service was opened */ - + become_root(); ret = smbrun( command , &fd ); unbecome_root(); - + DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret)); close(fd); - + + SAFE_FREE(command); + ZERO_STRUCTP( status ); status->type = 0x0020; status->state = (ret == 0 ) ? 0x0001 : 0x0004; @@ -51,19 +56,24 @@ static WERROR rcinit_stop( const char *service, SERVICE_STATUS *status ) static WERROR rcinit_start( const char *service ) { - pstring command; + char *command = NULL; int ret, fd; - - pstr_sprintf( command, "%s/%s/%s start", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service ); - + + if (asprintf(&command, "%s/%s/%s start", + dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service) < 0) { + return WERR_NOMEM; + } + /* we've already performed the access check when the service was opened */ - + become_root(); ret = smbrun( command , &fd ); unbecome_root(); - + DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret)); - close(fd); + close(fd); + + SAFE_FREE(command); return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED; } @@ -73,22 +83,27 @@ static WERROR rcinit_start( const char *service ) static WERROR rcinit_status( const char *service, SERVICE_STATUS *status ) { - pstring command; + char *command = NULL; int ret, fd; - - pstr_sprintf( command, "%s/%s/%s status", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service ); - + + if (asprintf(&command, "%s/%s/%s status", + dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service) < 0) { + return WERR_NOMEM; + } + /* we've already performed the access check when the service was opened */ /* assume as return code of 0 means that the service is ok. Anything else is STOPPED */ - + become_root(); ret = smbrun( command , &fd ); unbecome_root(); - + DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret)); close(fd); - + + SAFE_FREE(command); + ZERO_STRUCTP( status ); status->type = 0x0020; status->state = (ret == 0 ) ? 0x0004 : 0x0001; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index bb24db9ee1..323d78cde1 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1371,7 +1371,9 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, SSVAL(p,20,mode); p += 23; nameptr = p; - p += align_string(pdata, p, 0); + if (flags2 & FLAGS2_UNICODE_STRINGS) { + p += ucs2_align(base_data, p, 0); + } len = srvstr_push(base_data, flags2, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE); @@ -2022,7 +2024,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd if(got_exact_match) finished = True; - space_remaining = max_data_bytes - PTR_DIFF(p,pdata); + /* Ensure space_remaining never goes -ve. */ + if (PTR_DIFF(p,pdata) > max_data_bytes) { + space_remaining = 0; + out_of_space = true; + } else { + space_remaining = max_data_bytes - PTR_DIFF(p,pdata); + } } /* Check if we can close the dirptr */ diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 0b50ced0b9..18db15dfce 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -2180,6 +2180,7 @@ enum { int main(int argc, const char **argv) { + TALLOC_CTX *frame = talloc_stackframe(); int opt; static const char *helper_protocol; static int diagnostics; @@ -2361,5 +2362,6 @@ enum { /* Exit code */ poptFreeContext(pc); + TALLOC_FREE(frame); return 0; } diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 296c0630d8..b7fc65525a 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -233,8 +233,8 @@ static NTSTATUS password_change(const char *remote_mach, char *username, int local_flags) { NTSTATUS ret; - pstring err_str; - pstring msg_str; + char *err_str = NULL; + char *msg_str = NULL; if (remote_mach != NULL) { if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| @@ -250,13 +250,15 @@ static NTSTATUS password_change(const char *remote_mach, char *username, } ret = local_password_change(username, local_flags, new_pw, - err_str, sizeof(err_str), msg_str, sizeof(msg_str)); + &err_str, &msg_str); - if(*msg_str) + if(msg_str) printf("%s", msg_str); - if(*err_str) + if(err_str) fprintf(stderr, "%s", err_str); + SAFE_FREE(msg_str); + SAFE_FREE(err_str); return ret; } diff --git a/source3/web/swat.c b/source3/web/swat.c index e9ed0ded54..95921c0b1d 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -987,8 +987,8 @@ static bool change_password(const char *remote_machine, const char *user_name, int local_flags) { NTSTATUS ret; - pstring err_str; - pstring msg_str; + char *err_str = NULL; + char *msg_str = NULL; if (demo_mode) { printf("%s\n<p>", _("password change in demo mode rejected")); @@ -1008,14 +1008,16 @@ static bool change_password(const char *remote_machine, const char *user_name, return False; } - ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str), - msg_str, sizeof(msg_str)); + ret = local_password_change(user_name, local_flags, new_passwd, + &err_str, &msg_str); - if(*msg_str) + if(msg_str) printf("%s\n<p>", msg_str); - if(*err_str) + if(err_str) printf("%s\n<p>", err_str); + SAFE_FREE(msg_str); + SAFE_FREE(err_str); return NT_STATUS_IS_OK(ret); } diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 2167cfcdfc..4194b55894 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -61,9 +61,8 @@ static bool reload_services_file(void) bool ret; if (lp_loaded()) { - pstring fname; + const char *fname = lp_configfile(); - pstrcpy(fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) { pstrcpy(dyn_CONFIGFILE,fname); } @@ -129,12 +128,14 @@ static void flush_caches(void) static void terminate(void) { - pstring path; + char *path = NULL; /* Remove socket file */ - pstr_sprintf(path, "%s/%s", - get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME); - unlink(path); + if (asprintf(&path, "%s/%s", + get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) { + unlink(path); + SAFE_FREE(path); + } idmap_close(); @@ -983,7 +984,6 @@ static void process_loop(void) int main(int argc, char **argv, char **envp) { - pstring logfile; static bool is_daemon = False; static bool Fork = True; static bool log_stdout = False; @@ -1086,8 +1086,12 @@ int main(int argc, char **argv, char **envp) poptFreeContext(pc); if (!override_logfile) { - pstr_sprintf(logfile, "%s/log.winbindd", dyn_LOGFILEBASE); - lp_set_logfile(logfile); + char *logfile = NULL; + if (asprintf(&logfile,"%s/log.winbindd", + dyn_LOGFILEBASE) > 0) { + lp_set_logfile(logfile); + SAFE_FREE(logfile); + } } setup_logging("winbindd", log_stdout); reopen_logs(); diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 4c9ae0365f..f8e76b0299 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -923,6 +923,8 @@ static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx, } (*addrs)[*num] = *pss; + set_sockaddr_port(&(*addrs)[*num], port); + *num += 1; return True; } |