/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
* Copyright (c) 1991-1998 University of Maryland at College Park
* Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
* Copyright (c) 2013-2016 Carbonite, Inc. All Rights Reserved.
* All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of U.M. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. U.M. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
/*
* $Id: findpass.c,v 1.13 2006/05/25 01:47:11 johnfranks Exp $
*
* Support routines for Amanda SAMBA support
*/
#include "amanda.h"
#include "findpass.h"
#include "amutil.h"
/*
* Find the Samba password and optional domain for a given disk.
* Returns pointers into an g_malloc-ed area. The caller should clear them
* as soon as reasonable.
*/
char *
findpass(
char * disk,
char ** domain)
{
FILE *fp;
static char *buffer = NULL;
char *s, *d, *pw = NULL;
int ch;
char *qname;
*domain = NULL; /* just to be sure */
if ( (fp = fopen("/etc/amandapass", "r")) ) {
amfree(buffer);
for (; (buffer = agets(fp)) != NULL; free(buffer)) {
if (buffer[0] == '\0')
continue;
s = buffer;
ch = *s++;
skip_whitespace(s, ch); /* find start of disk name */
if (!ch || ch == '#') {
continue;
}
qname = s-1; /* start of disk name */
skip_quoted_string(s, ch);
if (ch && ch != '#') {
s[-1] = '\0'; /* terminate disk name */
d = unquote_string(qname);
if ((g_str_equal(d, "*")) || (g_str_equal(disk, d))) {
skip_whitespace(s, ch); /* find start of password */
if (ch && ch != '#') {
pw = s - 1; /* start of password */
skip_non_whitespace_cs(s, ch);
s[-1] = '\0'; /* terminate password */
pw = g_strdup(pw);
skip_whitespace(s, ch); /* find start of domain */
if (ch && ch != '#') {
*domain = s - 1; /* start of domain */
skip_non_whitespace_cs(s, ch);
s[-1] = '\0'; /* terminate domain */
*domain = g_strdup(*domain);
}
}
amfree(d);
break;
}
amfree(d);
}
}
afclose(fp);
}
return pw;
}
/*
* Convert an amanda disk-name into a Samba sharename,
* optionally for a shell execution (\'s are escaped).
* Returns a new name g_malloc-d that the caller is responsible
* for free-ing.
*/
char *
makesharename(
char * disk,
int shell)
{
char *buffer;
size_t buffer_size;
char *s;
int ch;
buffer_size = 2 * strlen(disk) + 1; /* worst case */
buffer = g_malloc(buffer_size);
s = buffer;
while ((ch = *disk++) != '\0') {
if (s >= buffer+buffer_size-2) { /* room for escape */
amfree(buffer); /* should never happen */
return NULL; /* buffer not big enough */
}
if (ch == '/') {
ch = '\\'; /* convert '/' to '\\' */
}
if (ch == '\\' && shell) {
*s++ = '\\'; /* add escape for shell */
}
*s++ = ch;
}
*s = '\0'; /* terminate the share name */
return buffer;
}
/*
* find out if the samba sharename specifies both a share
* and a target subdirectory or just a share
*
* the caller is expected to release share & subdir
*/
void
parsesharename(
char * disk,
char ** share,
char ** subdir)
{
char *ch=NULL;
int slashcnt=0;
*share = NULL;
*subdir = NULL;
if (!disk) {
return;
}
*share = g_strdup(disk);
ch = *share;
*subdir = NULL;
while (*ch != '\0') {
if (*ch == '/') {slashcnt++;}
if (slashcnt == 4) {
*ch = '\0';
*subdir = g_strdup(++ch);
return;
}
ch++;
}
}