From 1eb743ab8e8b1141f99fabd3e4a46895c6dcc17e Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 2 Dec 2008 23:29:57 -0800 Subject: s3: Change sockaddr util function names for consistency Also eliminates name conflicts with OneFS system libraries --- source3/client/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/client') diff --git a/source3/client/client.c b/source3/client/client.c index 39f8f90bba..da789161c9 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -4623,7 +4623,7 @@ static int do_message_op(void) snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type); fstrcat(server_name, name_type_hex); - zero_addr(&ss); + zero_sockaddr(&ss); if (have_ip) ss = dest_ss; -- cgit From 420a9071e1227435aada2a52c83ee44fda7180ed Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 5 Dec 2008 08:09:08 -0600 Subject: mount.cifs: if mount user not specified use USER environment variable smbfs also would use the USER environment variable if the user was not specified on the mount command and no credential file specified, and mount.cifs man page says that we will use this environment variable (in most cases this will not cause a behavior change, because we were doing getuid of the current process which will usually be the same name). Fixes Samba bug #5934 Acked-by: Jeff Layton --- source3/client/mount.cifs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/client') diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index da2f98bff8..0bc61ae38f 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -1293,7 +1293,13 @@ int main(int argc, char ** argv) } if(got_user == 0) { - user_name = getusername(); + /* Note that the password will not be retrieved from the + USER env variable (ie user%password form) as there is + already a PASSWD environment varaible */ + if (getenv("USER")) + user_name = strdup(getenv("USER")); + if (user_name == NULL) + user_name = getusername(); got_user = 1; } -- cgit From 9069c849074bc13dda505d461be97dd6357637aa Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 12 Dec 2008 07:00:38 -0500 Subject: mount.cifs: allow mounts to ipv6 capable servers The current name resolution scheme in mount.cifs is IPv4 only. Expand it to be protocol-independent. Also take advantage of the fact that getaddrinfo() returns a list of addresses and have mount.cifs try each in turn until it hits one that's reachable and allows the socket to connect. Signed-off-by: Jeff Layton --- source3/client/mount.cifs.c | 221 ++++++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 101 deletions(-) (limited to 'source3/client') diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 0bc61ae38f..9f4d1d3fd0 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -80,6 +80,9 @@ #define MOUNT_PASSWD_SIZE 64 #define DOMAIN_SIZE 64 +/* currently maximum length of IPv6 address string */ +#define MAX_ADDRESS_LEN INET6_ADDRSTRLEN + const char *thisprogram; int verboseflag = 0; static int got_password = 0; @@ -189,12 +192,6 @@ static char * getusername(void) { return username; } -static char * parse_cifs_url(char * unc_name) -{ - printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n",unc_name); - return NULL; -} - static int open_cred_file(char * file_name) { char * line_buf; @@ -494,7 +491,7 @@ static int parse_options(char ** optionsp, int * filesys_flags) } else if (strncmp(data, "ip", 2) == 0) { if (!value || !*value) { printf("target ip address argument missing"); - } else if (strnlen(value, 35) < 35) { + } else if (strnlen(value, MAX_ADDRESS_LEN) <= MAX_ADDRESS_LEN) { if(verboseflag) printf("ip address %s override specified\n",value); got_ip = 1; @@ -882,23 +879,23 @@ static void replace_char(char *string, char from, char to, int maxlen) } /* Note that caller frees the returned buffer if necessary */ -static char * parse_server(char ** punc_name) +static struct addrinfo * +parse_server(char ** punc_name) { char * unc_name = *punc_name; int length = strnlen(unc_name, MAX_UNC_LEN); char * share; - char * ipaddress_string = NULL; - struct hostent * host_entry = NULL; - struct in_addr server_ipaddr; + struct addrinfo *addrlist; + int rc; if(length > (MAX_UNC_LEN - 1)) { printf("mount error: UNC name too long"); return NULL; } - if (strncasecmp("cifs://",unc_name,7) == 0) - return parse_cifs_url(unc_name+7); - if (strncasecmp("smb://",unc_name,6) == 0) { - return parse_cifs_url(unc_name+6); + if ((strncasecmp("cifs://", unc_name, 7) == 0) || + (strncasecmp("smb://", unc_name, 6) == 0)) { + printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n", unc_name); + return NULL; } if(length < 3) { @@ -939,7 +936,12 @@ continue_unc_parsing: *share = 0; /* temporarily terminate the string */ share += 1; if(got_ip == 0) { - host_entry = gethostbyname(unc_name); + rc = getaddrinfo(unc_name, NULL, NULL, &addrlist); + if (rc != 0) { + printf("mount error: could not resolve address for %s: %s\n", + unc_name, gai_strerror(rc)); + addrlist = NULL; + } } *(share - 1) = '/'; /* put delimiter back */ @@ -954,23 +956,9 @@ continue_unc_parsing: printf("ip address specified explicitly\n"); return NULL; } - if(host_entry == NULL) { - printf("mount error: could not find target server. TCP name %s not found\n", unc_name); - return NULL; - } else { - /* BB should we pass an alternate version of the share name as Unicode */ - /* BB what about ipv6? BB */ - /* BB add retries with alternate servers in list */ + /* BB should we pass an alternate version of the share name as Unicode */ - memcpy(&server_ipaddr.s_addr, host_entry->h_addr, 4); - - ipaddress_string = inet_ntoa(server_ipaddr); - if(ipaddress_string == NULL) { - printf("mount error: could not get valid ip address for target server\n"); - return NULL; - } - return ipaddress_string; - } + return addrlist; } else { /* BB add code to find DFS root (send null path on get DFS Referral to specified server here */ printf("Mounting the DFS root for a particular server not implemented yet\n"); @@ -1034,10 +1022,11 @@ int main(int argc, char ** argv) int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */ char * orgoptions = NULL; char * share_name = NULL; - char * ipaddr = NULL; + const char * ipaddr = NULL; char * uuid = NULL; char * mountpoint = NULL; char * options = NULL; + char * optionstail; char * resolved_path = NULL; char * temp; char * dev_name; @@ -1050,10 +1039,14 @@ int main(int argc, char ** argv) int optlen = 0; int orgoptlen = 0; size_t options_size = 0; + size_t current_len; int retry = 0; /* set when we have to retry mount with uppercase */ + struct addrinfo *addrhead = NULL, *addr; struct stat statbuf; struct utsname sysinfo; struct mntent mountent; + struct sockaddr_in *addr4; + struct sockaddr_in6 *addr6; FILE * pmntfile; /* setlocale(LC_ALL, ""); @@ -1245,8 +1238,8 @@ int main(int argc, char ** argv) rc = EX_USAGE; goto mount_exit; } - ipaddr = parse_server(&share_name); - if((ipaddr == NULL) && (got_ip == 0)) { + addrhead = addr = parse_server(&share_name); + if((addrhead == NULL) && (got_ip == 0)) { printf("No ip address specified and hostname not found\n"); rc = EX_USAGE; goto mount_exit; @@ -1316,7 +1309,6 @@ int main(int argc, char ** argv) } /* FIXME launch daemon (handles dfs name resolution and credential change) remember to clear parms and overwrite password field before launching */ -mount_retry: if(orgoptions) { optlen = strlen(orgoptions); orgoptlen = optlen; @@ -1331,10 +1323,10 @@ mount_retry: } if(user_name) optlen += strlen(user_name) + 6; - if(ipaddr) - optlen += strlen(ipaddr) + 4; + optlen += MAX_ADDRESS_LEN + 4; if(mountpassword) optlen += strlen(mountpassword) + 6; +mount_retry: SAFE_FREE(options); options_size = optlen + 10 + DOMAIN_SIZE; options = (char *)malloc(options_size /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */); @@ -1344,18 +1336,12 @@ mount_retry: exit(EX_SYSERR); } - options[0] = 0; - strlcpy(options,"unc=",options_size); + strlcpy(options, "unc=", options_size); strlcat(options,share_name,options_size); /* scan backwards and reverse direction of slash */ temp = strrchr(options, '/'); if(temp > options + 6) *temp = '\\'; - if(ipaddr) { - strlcat(options,",ip=",options_size); - strlcat(options,ipaddr,options_size); - } - if(user_name) { /* check for syntax like user=domain\user */ if(got_domain == 0) @@ -1397,11 +1383,42 @@ mount_retry: /* convert all '\\' to '/' in share portion so that /proc/mounts looks pretty */ replace_char(dev_name, '\\', '/', strlen(share_name)); - if(mount(dev_name, mountpoint, "cifs", flags, options)) { - /* remember to kill daemon on error */ + if (!got_ip && addr) { + strlcat(options, ",ip=", options_size); + current_len = strnlen(options, options_size); + optionstail = options + current_len; + switch (addr->ai_addr->sa_family) { + case AF_INET6: + addr6 = (struct sockaddr_in6 *) addr->ai_addr; + ipaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, optionstail, + options_size - current_len); + break; + case AF_INET: + addr4 = (struct sockaddr_in *) addr->ai_addr; + ipaddr = inet_ntop(AF_INET, &addr4->sin_addr, optionstail, + options_size - current_len); + break; + } + + /* if the address looks bogus, try the next one */ + if (!ipaddr) { + addr = addr->ai_next; + if (addr) + goto mount_retry; + rc = EX_SYSERR; + goto mount_exit; + } + } + + if (mount(dev_name, mountpoint, "cifs", flags, options)) { switch (errno) { - case 0: - printf("mount failed but no error number set\n"); + case ECONNREFUSED: + case EHOSTUNREACH: + if (addr) { + addr = addr->ai_next; + if (addr) + goto mount_retry; + } break; case ENODEV: printf("mount error: cifs filesystem not supported by the system\n"); @@ -1416,64 +1433,64 @@ mount_retry: goto mount_retry; } } - default: - printf("mount error %d = %s\n",errno,strerror(errno)); } + printf("mount error(%d): %s\n", errno, strerror(errno)); printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); rc = EX_FAIL; - } else { - atexit(unlock_mtab); - rc = lock_mtab(); - if (rc) { - printf("cannot lock mtab"); - goto mount_exit; - } - pmntfile = setmntent(MOUNTED, "a+"); - if (!pmntfile) { - printf("could not update mount table\n"); - unlock_mtab(); - rc = EX_FILEIO; - goto mount_exit; - } - mountent.mnt_fsname = dev_name; - mountent.mnt_dir = mountpoint; - mountent.mnt_type = CONST_DISCARD(char *,"cifs"); - mountent.mnt_opts = (char *)malloc(220); - if(mountent.mnt_opts) { - char * mount_user = getusername(); - memset(mountent.mnt_opts,0,200); - if(flags & MS_RDONLY) - strlcat(mountent.mnt_opts,"ro",220); - else - strlcat(mountent.mnt_opts,"rw",220); - if(flags & MS_MANDLOCK) - strlcat(mountent.mnt_opts,",mand",220); - if(flags & MS_NOEXEC) - strlcat(mountent.mnt_opts,",noexec",220); - if(flags & MS_NOSUID) - strlcat(mountent.mnt_opts,",nosuid",220); - if(flags & MS_NODEV) - strlcat(mountent.mnt_opts,",nodev",220); - if(flags & MS_SYNCHRONOUS) - strlcat(mountent.mnt_opts,",sync",220); - if(mount_user) { - if(getuid() != 0) { - strlcat(mountent.mnt_opts, - ",user=", 220); - strlcat(mountent.mnt_opts, - mount_user, 220); - } + goto mount_exit; + } + + atexit(unlock_mtab); + rc = lock_mtab(); + if (rc) { + printf("cannot lock mtab"); + goto mount_exit; + } + pmntfile = setmntent(MOUNTED, "a+"); + if (!pmntfile) { + printf("could not update mount table\n"); + unlock_mtab(); + rc = EX_FILEIO; + goto mount_exit; + } + mountent.mnt_fsname = dev_name; + mountent.mnt_dir = mountpoint; + mountent.mnt_type = CONST_DISCARD(char *,"cifs"); + mountent.mnt_opts = (char *)malloc(220); + if(mountent.mnt_opts) { + char * mount_user = getusername(); + memset(mountent.mnt_opts,0,200); + if(flags & MS_RDONLY) + strlcat(mountent.mnt_opts,"ro",220); + else + strlcat(mountent.mnt_opts,"rw",220); + if(flags & MS_MANDLOCK) + strlcat(mountent.mnt_opts,",mand",220); + if(flags & MS_NOEXEC) + strlcat(mountent.mnt_opts,",noexec",220); + if(flags & MS_NOSUID) + strlcat(mountent.mnt_opts,",nosuid",220); + if(flags & MS_NODEV) + strlcat(mountent.mnt_opts,",nodev",220); + if(flags & MS_SYNCHRONOUS) + strlcat(mountent.mnt_opts,",sync",220); + if(mount_user) { + if(getuid() != 0) { + strlcat(mountent.mnt_opts, + ",user=", 220); + strlcat(mountent.mnt_opts, + mount_user, 220); } } - mountent.mnt_freq = 0; - mountent.mnt_passno = 0; - rc = addmntent(pmntfile,&mountent); - endmntent(pmntfile); - unlock_mtab(); - SAFE_FREE(mountent.mnt_opts); - if (rc) - rc = EX_FILEIO; } + mountent.mnt_freq = 0; + mountent.mnt_passno = 0; + rc = addmntent(pmntfile,&mountent); + endmntent(pmntfile); + unlock_mtab(); + SAFE_FREE(mountent.mnt_opts); + if (rc) + rc = EX_FILEIO; mount_exit: if(mountpassword) { int len = strlen(mountpassword); @@ -1481,6 +1498,8 @@ mount_exit: SAFE_FREE(mountpassword); } + if (addrhead) + freeaddrinfo(addrhead); SAFE_FREE(options); SAFE_FREE(orgoptions); SAFE_FREE(resolved_path); -- cgit From daeb3a190d16a5bc05be63b2b136ebe65d6f6cf7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 14 Dec 2008 13:06:19 +0100 Subject: Remove the global "cmdline_auth_info" from source3/lib/util.c This involves changing all our clients, that's why it's so large. --- source3/client/client.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'source3/client') diff --git a/source3/client/client.c b/source3/client/client.c index da789161c9..c88b918dc8 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -218,13 +218,12 @@ static int readfile(char *b, int n, XFILE *f) Send a message. ****************************************************************************/ -static void send_message(void) +static void send_message(const char *username) { int total_len = 0; int grp_id; - if (!cli_message_start(cli, desthost, - get_cmdline_auth_info_username(), &grp_id)) { + if (!cli_message_start(cli, desthost, username, &grp_id)) { d_printf("message start: %s\n", cli_errstr(cli)); return; } @@ -4607,7 +4606,7 @@ static int do_tar_op(const char *base_directory) Handle a message operation. ****************************************************************************/ -static int do_message_op(void) +static int do_message_op(struct user_auth_info *auth_info) { struct sockaddr_storage ss; struct nmb_name called, calling; @@ -4648,7 +4647,7 @@ static int do_message_op(void) return 1; } - send_message(); + send_message(get_cmdline_auth_info_username(auth_info)); cli_cm_shutdown(); return 0; @@ -4695,6 +4694,7 @@ static int do_message_op(void) POPT_TABLEEND }; TALLOC_CTX *frame = talloc_stackframe(); + struct user_auth_info *auth_info; if (!client_set_cur_dir("\\")) { exit(ENOMEM); @@ -4724,6 +4724,12 @@ static int do_message_op(void) load_case_tables(); + auth_info = user_auth_info_init(frame); + if (auth_info == NULL) { + exit(1); + } + popt_common_set_auth_info(auth_info); + /* skip argv(0) */ pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 0); poptSetOtherOptionHelp(pc, "service "); @@ -4751,8 +4757,11 @@ static int do_message_op(void) } /* if the service has already been retrieved then check if we have also a password */ - if (service_opt && (!get_cmdline_auth_info_got_pass()) && poptPeekArg(pc)) { - set_cmdline_auth_info_password(poptGetArg(pc)); + if (service_opt + && (!get_cmdline_auth_info_got_pass(auth_info)) + && poptPeekArg(pc)) { + set_cmdline_auth_info_password(auth_info, + poptGetArg(pc)); } switch (opt) { @@ -4858,8 +4867,11 @@ static int do_message_op(void) } /* if the service has already been retrieved then check if we have also a password */ - if (service_opt && !get_cmdline_auth_info_got_pass() && poptPeekArg(pc)) { - set_cmdline_auth_info_password(poptGetArg(pc)); + if (service_opt + && !get_cmdline_auth_info_got_pass(auth_info) + && poptPeekArg(pc)) { + set_cmdline_auth_info_password(auth_info, + poptGetArg(pc)); } /* check for the -P option */ @@ -4893,8 +4905,8 @@ static int do_message_op(void) argv[0], get_dyn_CONFIGFILE()); } - if (get_cmdline_auth_info_use_machine_account() && - !set_cmdline_auth_info_machine_account_creds()) { + if (get_cmdline_auth_info_use_machine_account(auth_info) && + !set_cmdline_auth_info_machine_account_creds(auth_info)) { exit(-1); } @@ -4929,7 +4941,7 @@ static int do_message_op(void) calling_name = talloc_strdup(frame, global_myname() ); } - smb_encrypt = get_cmdline_auth_info_smb_encrypt(); + smb_encrypt = get_cmdline_auth_info_smb_encrypt(auth_info); if (!init_names()) { fprintf(stderr, "init_names() failed\n"); exit(1); @@ -4947,7 +4959,7 @@ static int do_message_op(void) /* Store the username and password for dfs support */ - cli_cm_set_credentials(); + cli_cm_set_credentials(auth_info); DEBUG(3,("Client started (version %s).\n", SAMBA_VERSION_STRING)); @@ -4980,7 +4992,7 @@ static int do_message_op(void) } if (message) { - return do_message_op(); + return do_message_op(auth_info); } if (process(base_directory)) { -- cgit