From patchwork Fri Mar 26 14:25:27 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 88499 Received: from lists.samba.org (fn.samba.org [216.83.154.106]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2QEPs3D011238 for ; Fri, 26 Mar 2010 14:26:32 GMT Received: from fn.samba.org (localhost [127.0.0.1]) by lists.samba.org (Postfix) with ESMTP id 743E14663C; Fri, 26 Mar 2010 08:25:55 -0600 (MDT) X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on fn.samba.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.8 tests=BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS,SPF_NEUTRAL autolearn=ham version=3.2.5 X-Original-To: linux-cifs-client@lists.samba.org Delivered-To: linux-cifs-client@lists.samba.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by lists.samba.org (Postfix) with ESMTP id 1955046645 for ; Fri, 26 Mar 2010 08:25:44 -0600 (MDT) Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o2QEPhn7025279 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 26 Mar 2010 10:25:43 -0400 Received: from localhost.localdomain (vpn-10-105.rdu.redhat.com [10.11.10.105]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2QEPdCZ026868 for ; Fri, 26 Mar 2010 10:25:42 -0400 From: Jeff Layton To: linux-cifs-client@lists.samba.org Date: Fri, 26 Mar 2010 10:25:27 -0400 Message-Id: <1269613542-6402-5-git-send-email-jlayton@samba.org> In-Reply-To: <1269613542-6402-1-git-send-email-jlayton@samba.org> References: <1269613542-6402-1-git-send-email-jlayton@samba.org> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 Subject: [linux-cifs-client] [PATCH 04/19] mount.cifs: make mountpassword a field in parsed_info X-BeenThere: linux-cifs-client@lists.samba.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: The Linux CIFS VFS client List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-cifs-client-bounces@lists.samba.org Errors-To: linux-cifs-client-bounces@lists.samba.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Fri, 26 Mar 2010 14:26:32 +0000 (UTC) diff --git a/mount.cifs.c b/mount.cifs.c index c0cc13f..86edae8 100644 --- a/mount.cifs.c +++ b/mount.cifs.c @@ -125,13 +125,14 @@ struct parsed_mount_info { char share[MAX_SHARE_LEN]; char prefix[PATH_MAX]; char options[MAX_OPTIONS_LEN]; + char password[MOUNT_PASSWD_SIZE + 1]; char address_list[MAX_ADDR_LIST_LEN]; + unsigned int got_password:1; }; const char *thisprogram; int verboseflag = 0; int fakemnt = 0; -static int got_password = 0; static int got_user = 0; static int got_domain = 0; static int got_ip = 0; @@ -139,7 +140,6 @@ static int got_unc = 0; static int got_uid = 0; static int got_gid = 0; static char * user_name = NULL; -static char * mountpassword = NULL; char * domain_name = NULL; char * prefixpath = NULL; const char *cifs_fstype = "cifs"; @@ -297,7 +297,7 @@ static char * getusername(void) { return username; } -static int open_cred_file(char * file_name) +static int open_cred_file(char *file_name, struct parsed_mount_info *parsed_info) { char * line_buf; char * temp_val; @@ -364,18 +364,11 @@ static int open_cred_file(char * file_name) } if(length > MOUNT_PASSWD_SIZE) { fprintf(stderr, "mount.cifs failed: password in credentials file too long\n"); - memset(line_buf,0, 4096); + memset(line_buf, 0, 4096); return EX_USAGE; - } else { - if(mountpassword == NULL) { - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - } else - memset(mountpassword,0,MOUNT_PASSWD_SIZE); - if(mountpassword) { - strlcpy(mountpassword,temp_val,MOUNT_PASSWD_SIZE+1); - got_password = 1; - } } + strlcpy(parsed_info->password, temp_val, MOUNT_PASSWD_SIZE + 1); + parsed_info->got_password = 1; } } else if (strncasecmp("domain",line_buf+i,6) == 0) { temp_val = strchr(line_buf+i,'='); @@ -413,22 +406,13 @@ static int open_cred_file(char * file_name) return 0; } -static int get_password_from_file(int file_descript, char * filename) +static int +get_password_from_file(int file_descript, char *filename, struct parsed_mount_info *parsed_info) { int rc = 0; int i; char c; - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - else - memset(mountpassword, 0, MOUNT_PASSWD_SIZE); - - if (mountpassword == NULL) { - fprintf(stderr, "malloc failed\n"); - return EX_SYSERR; - } - if(filename != NULL) { rc = access(filename, R_OK); if (rc) { @@ -453,24 +437,24 @@ static int get_password_from_file(int file_descript, char * filename) close(file_descript); return EX_SYSERR; } else if(rc == 0) { - if(mountpassword[0] == 0) { + if(parsed_info->password[0] == 0) { if(verboseflag) fprintf(stderr, "\nWarning: null password used since cifs password file empty"); } break; } else /* read valid character */ { if((c == 0) || (c == '\n')) { - mountpassword[i] = '\0'; + parsed_info->password[i] = '\0'; break; } else - mountpassword[i] = c; + parsed_info->password[i] = c; } } if((i == MOUNT_PASSWD_SIZE) && (verboseflag)) { fprintf(stderr, "\nWarning: password longer than %d characters specified in cifs password file", MOUNT_PASSWD_SIZE); } - got_password = 1; + parsed_info->got_password = 1; if(filename != NULL) { close(file_descript); } @@ -549,19 +533,15 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) percent_char = strchr(value,'%'); if(percent_char) { *percent_char = ','; - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if(mountpassword) { - if(got_password) - fprintf(stderr, "\nmount.cifs warning - password specified twice\n"); - got_password = 1; - percent_char++; - strlcpy(mountpassword, percent_char,MOUNT_PASSWD_SIZE+1); + if(parsed_info->got_password) + fprintf(stderr, "\nmount.cifs warning - password specified twice\n"); + parsed_info->got_password = 1; + percent_char++; + strlcpy(parsed_info->password, percent_char, sizeof(parsed_info->password)); /* remove password from username */ - while(*percent_char != 0) { - *percent_char = ','; - percent_char++; - } + while(*percent_char != 0) { + *percent_char = ','; + percent_char++; } } /* this is only case in which the user @@ -578,20 +558,16 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } } else if (strncmp(data, "pass", 4) == 0) { if (!value || !*value) { - if(got_password) { + if(parsed_info->got_password) { fprintf(stderr, "\npassword specified twice, ignoring second\n"); } else - got_password = 1; + parsed_info->got_password = 1; } else if (strnlen(value, MOUNT_PASSWD_SIZE) < MOUNT_PASSWD_SIZE) { - if (got_password) { + if (parsed_info->got_password) { fprintf(stderr, "\nmount.cifs warning - password specified twice\n"); } else { - mountpassword = strndup(value, MOUNT_PASSWD_SIZE); - if (!mountpassword) { - fprintf(stderr, "mount.cifs error: %s", strerror(ENOMEM)); - return EX_USAGE; - } - got_password = 1; + strlcpy(parsed_info->password, value, MOUNT_PASSWD_SIZE + 1); + parsed_info->got_password = 1; } } else { fprintf(stderr, "password too long\n"); @@ -602,7 +578,7 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) if (value) { if (!strncmp(value, "none", 4) || !strncmp(value, "krb5", 4)) - got_password = 1; + parsed_info->got_password = 1; } } else if (strncmp(data, "ip", 2) == 0) { if (!value || !*value) { @@ -662,7 +638,7 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } } else if (strncmp(data, "cred", 4) == 0) { if (value && *value) { - rc = open_cred_file(value); + rc = open_cred_file(value, parsed_info); if (rc) { fprintf(stderr, "error %d (%s) opening credential file %s\n", rc, strerror(rc), value); @@ -757,7 +733,7 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } else if (strncmp(data, "guest", 5) == 0) { user_name = (char *)calloc(1, 1); got_user = 1; - got_password = 1; + parsed_info->got_password = 1; } else if (strncmp(data, "ro", 2) == 0) { *filesys_flags |= MS_RDONLY; goto nocopy; @@ -829,51 +805,29 @@ nocopy: } /* replace all (one or more) commas with double commas */ -static void check_for_comma(char ** ppasswrd) +static int +replace_commas(char *pass) { - char *new_pass_buf; - char *pass; - int i,j; - int number_of_commas = 0; - int len; - - if(ppasswrd == NULL) - return; - else - (pass = *ppasswrd); - - len = strlen(pass); - - for(i=0;i MOUNT_PASSWD_SIZE) { - /* would otherwise overflow the mount options buffer */ - fprintf(stderr, "\nInvalid password. Password contains too many commas.\n"); - return; - } - - new_pass_buf = (char *)malloc(len+number_of_commas+1); - if(new_pass_buf == NULL) - return; + /* don't do anything if there are no commas */ + if (!strchr(pass, ',')) + return 0; - for(i=0,j=0;i MOUNT_PASSWD_SIZE + 1) { + fprintf(stderr, "Converted password too long!\n"); + return EX_USAGE; } } - new_pass_buf[len+number_of_commas] = 0; - - SAFE_FREE(*ppasswrd); - *ppasswrd = new_pass_buf; - - return; + tmpbuf[j] = '\0'; + strlcpy(pass, tmpbuf, MOUNT_PASSWD_SIZE + 1); + return 0; } /* Usernames can not have backslash in them and we use @@ -1053,6 +1007,22 @@ parse_server(char **punc_name) return addrlist; } +static int +get_pw_from_env(struct parsed_mount_info *parsed_info) +{ + int rc = 0; + + if (getenv("PASSWD")) { + strlcpy(parsed_info->password, getenv("PASSWD"), MOUNT_PASSWD_SIZE + 1); + parsed_info->got_password = 1; + } else if (getenv("PASSWD_FD")) + rc = get_password_from_file(atoi(getenv("PASSWD_FD")), NULL, parsed_info); + else if (getenv("PASSWD_FILE")) + rc = get_password_from_file(0, getenv("PASSWD_FILE"), parsed_info); + + return rc; +} + static struct option longopts[] = { { "all", 0, NULL, 'a' }, { "help",0, NULL, 'h' }, @@ -1293,15 +1263,11 @@ int main(int argc, char ** argv) got_domain = 1; break; case 'p': - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if(mountpassword) { - got_password = 1; - strlcpy(mountpassword,optarg,MOUNT_PASSWD_SIZE+1); - } + strlcpy(parsed_info->password, optarg, sizeof(parsed_info->password)); + parsed_info->got_password = 1; break; case 'S': - rc = get_password_from_file(0 /* stdin */,NULL); + rc = get_password_from_file(0, NULL, parsed_info); if (rc) goto mount_exit; break; @@ -1355,22 +1321,9 @@ int main(int argc, char ** argv) parsed_info->flags |= CIFS_SETUID_FLAGS; } - if (getenv("PASSWD")) { - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if(mountpassword) { - strlcpy(mountpassword,getenv("PASSWD"),MOUNT_PASSWD_SIZE+1); - got_password = 1; - } - } else if (getenv("PASSWD_FD")) { - rc = get_password_from_file(atoi(getenv("PASSWD_FD")),NULL); - if (rc) - goto mount_exit; - } else if (getenv("PASSWD_FILE")) { - rc = get_password_from_file(0, getenv("PASSWD_FILE")); - if (rc) - goto mount_exit; - } + rc = get_pw_from_env(parsed_info); + if (rc) + goto mount_exit; options = calloc(options_size, 1); if (!options) { @@ -1442,17 +1395,16 @@ int main(int argc, char ** argv) got_user = 1; } - if(got_password == 0) { + if(!parsed_info->got_password) { char *tmp_pass = getpass("Password: "); /* BB obsolete sys call but no good replacement yet. */ - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if (!tmp_pass || !mountpassword) { + if (!tmp_pass) { fprintf(stderr, "Password not entered, exiting\n"); rc = EX_USAGE; goto mount_exit; } - strlcpy(mountpassword, tmp_pass, MOUNT_PASSWD_SIZE+1); - got_password = 1; + strlcpy(parsed_info->password, tmp_pass, sizeof(parsed_info->password)); + parsed_info->got_password = 1; } if(!share_name) { @@ -1543,15 +1495,15 @@ mount_retry: if(verboseflag) fprintf(stderr, "\nmount.cifs kernel mount options: %s", options); - if (mountpassword) { + if (parsed_info->got_password) { /* * Commas have to be doubled, or else they will * look like the parameter separator */ if(retry == 0) - check_for_comma(&mountpassword); - strlcat(options,",pass=",options_size); - strlcat(options,mountpassword,options_size); + replace_commas(parsed_info->password); + strlcat(options, ",pass=", options_size); + strlcat(options, parsed_info->password, options_size); if (verboseflag) fprintf(stderr, ",pass=********"); } @@ -1648,14 +1600,10 @@ mount_retry: if (rc) rc = EX_FILEIO; mount_exit: - if(mountpassword) { - int len = strlen(mountpassword); - memset(mountpassword,0,len); - SAFE_FREE(mountpassword); - } - if (addrhead) freeaddrinfo(addrhead); + memset(parsed_info->password, 0, sizeof(parsed_info->password)); + SAFE_FREE(parsed_info); SAFE_FREE(options); SAFE_FREE(orgoptions); SAFE_FREE(resolved_path);