// Returns true if the contents of |file| match |contents|.
static PRBool CheckFileContents(nsILocalFile *file, const char *contents)
{
  nsCString nativePath;
  file->GetNativePath(nativePath);

  // Now read in the file contents and compare to the expected output
  PRFileInfo info;
  ASSERT_TRUE_RET(PR_GetFileInfo(nativePath.get(), &info) == PR_SUCCESS,
                  PR_FALSE);

  char *buf = new char[info.size + 1];
  ASSERT_TRUE_RET(buf, PR_FALSE);

  PRFileDesc *fd = PR_Open(nativePath.get(), PR_RDONLY, 0);
  ASSERT_TRUE_RET(fd, PR_FALSE);

  ASSERT_TRUE_RET(PR_Read(fd, buf, info.size) == info.size, PR_FALSE);
  PR_Close(fd);
  buf[info.size] = '\0';

  // Leave the file in place if the test failed
  ASSERT_TRUE_RET(!strcmp(buf, contents), PR_FALSE);
  PR_Delete(nativePath.get());
  delete[] buf;
  return PR_TRUE;
}
Ejemplo n.º 2
0
void RNG_FileForRNG(const char *filename)
{
    PRFileDesc *    file;
    int             nBytes;
    PRFileInfo      infoBuf;
    unsigned char   buffer[1024];

    if (PR_GetFileInfo(filename, &infoBuf) != PR_SUCCESS)
        return;

    RNG_RandomUpdate((unsigned char*)&infoBuf, sizeof(infoBuf));

    file = PR_Open(filename, PR_RDONLY, 0);
    if (file != NULL) {
        for (;;) {
            PRInt32 bytes = PR_Read(file, buffer, sizeof buffer);

            if (bytes <= 0)
                break;

            RNG_RandomUpdate(buffer, bytes);
            totalFileBytes += bytes;
            if (totalFileBytes > maxFileBytes)
                break;
        }

        PR_Close(file);
    }

    nBytes = RNG_GetNoise(buffer, 20);  // get up to 20 bytes
    RNG_RandomUpdate(buffer, nBytes);
}
Ejemplo n.º 3
0
Archivo: misc.c Proyecto: leto/389-ds
/* mkdir -p */
int
mkdir_p(char *dir, unsigned int mode)
{
    PRFileInfo info;
    int rval;
    char sep = get_sep(dir);

    rval = PR_GetFileInfo(dir, &info);
    if (PR_SUCCESS == rval)
    {
        if (PR_FILE_DIRECTORY != info.type)    /* not a directory */
        {
            PR_Delete(dir);
            if (PR_SUCCESS != PR_MkDir(dir, mode))
            {
                LDAPDebug(LDAP_DEBUG_ANY, "mkdir_p %s: error %d (%s)\n",
                    dir, PR_GetError(),slapd_pr_strerror(PR_GetError()));
                return -1;
            }
        }
        return 0;
    }
    else
    {
        /* does not exist */
        char *p, *e;
        char c[2] = {0, 0};
        int len = strlen(dir);
        rval = 0;

        e = dir + len - 1;
        if (*e == sep)
        {
            c[1] = *e;
            *e = '\0';
        }

        c[0] = '/';
        p = strrchr(dir, sep);
        if (NULL != p)
        {
            *p = '\0';
            rval = mkdir_p(dir, mode);
            *p = c[0];
        }
        if (c[1])
            *e = c[1];
        if (0 != rval)
            return rval;
        if (PR_SUCCESS != PR_MkDir(dir, mode))
        {
            LDAPDebug(LDAP_DEBUG_ANY, "mkdir_p %s: error %d (%s)\n",
                    dir, PR_GetError(),slapd_pr_strerror(PR_GetError()));
            return -1;
        }
        return 0;
    }
}
Ejemplo n.º 4
0
/***************************************************************************
 *
 * m a k e _ d i r s
 *
 * Ensure that the directory portion of the path exists.  This may require
 * making the directory, and its parent, and its parent's parent, etc.
 */
static int
make_dirs(char *path, int file_perms)
{
    char *Path;
    char *start;
    char *sep;
    int ret = 0;
    PRFileInfo info;

    if (!path) {
        return 0;
    }

    Path = PR_Strdup(path);
    start = strpbrk(Path, "/\\");
    if (!start) {
        return 0;
    }
    start++; /* start right after first slash */

    /* Each time through the loop add one more directory. */
    while ((sep = strpbrk(start, "/\\"))) {
        *sep = '\0';

        if (PR_GetFileInfo(Path, &info) != PR_SUCCESS) {
            /* No such dir, we have to create it */
            if (PR_MkDir(Path, dir_perms(file_perms)) != PR_SUCCESS) {
                error(PK11_INSTALL_CREATE_DIR, Path);
                ret = PK11_INSTALL_CREATE_DIR;
                goto loser;
            }
        } else {
            /* something exists by this name, make sure it's a directory */
            if (info.type != PR_FILE_DIRECTORY) {
                error(PK11_INSTALL_CREATE_DIR, Path);
                ret = PK11_INSTALL_CREATE_DIR;
                goto loser;
            }
        }

        /* If this is the lowest directory level, make sure it is writeable */
        if (!strpbrk(sep + 1, "/\\")) {
            if (PR_Access(Path, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
                error(PK11_INSTALL_DIR_NOT_WRITEABLE, Path);
                ret = PK11_INSTALL_DIR_NOT_WRITEABLE;
                goto loser;
            }
        }

        start = sep + 1; /* start after the next slash */
        *sep = '/';
    }

loser:
    PR_Free(Path);
    return ret;
}
Ejemplo n.º 5
0
static void statPRStat(void)
{
    PRFileInfo finfo;
    PRInt32 index = count;
 
    for (;index--;) {
         PR_GetFileInfo(filename, &finfo);
    }
}
Ejemplo n.º 6
0
SKERR SKIntegerList::SetFileName(const char *pszFileName,
                                 const char *pszDefaultFileName)
{
    m_bInitialized = PR_FALSE;

    if(m_bOwner && m_pIntegerList)
    {
        delete[] (PRUint32 *)m_pIntegerList;
        m_pIntegerList = NULL;
    }

    SKERR err = SKFile::SetFileName(pszFileName, pszDefaultFileName);
    if(err != noErr)
        return err;

    PRFileInfo info;
    if(PR_GetFileInfo(GetSharedFileName(), &info) != PR_SUCCESS)
        return err_failure;

    if((info.size & 0x3))
        return err_failure;

    PRFileDesc *f = skPR_Open(GetSharedFileName(), PR_RDONLY, 0);
    if(!f)
        return err_notfound;

    m_bOwner = PR_TRUE;
    m_iSize = info.size / 4;
    m_pIntegerList = new PRUint32[m_iSize];
    if(m_iSize && !m_pIntegerList)
    {
        PR_Close(f);
        return err_memory;
    }

    if(PR_Read(f, (void *)m_pIntegerList, info.size) != info.size)
    {
        PR_Close(f);
        return err_failure;
    }

#if IS_BIG_ENDIAN
    for(PRUint32 i = 0; i < m_iSize; ++i)
    {
        REVERSE_32(((PRUint32*)m_pIntegerList)[i]);
    }
#endif

    PR_Close(f);

    qsort((void *)m_pIntegerList, m_iSize, sizeof(PRUint32), &g_sComparePRUint32);
    m_bInitialized = PR_TRUE;

    return noErr;
}
Ejemplo n.º 7
0
std::string
CommandEventHandler::isDir(std::string path)
{
  // check if path exists and it is a dir
  PRFileInfo info;
  const char *p = path.c_str();
  PRStatus success = PR_GetFileInfo(p, &info);
  if (success == PR_SUCCESS && info.type == PR_FILE_DIRECTORY)
    return std::string("TRUE");
  return std::string("FALSE");
}
Ejemplo n.º 8
0
int wf_isFileDirectory(const char *filename)
{
	if (!filename || !*filename)
		return (0);

	PRFileInfo finfo;

	if (PR_GetFileInfo(filename, &finfo) == PR_FAILURE)
		return (0);

	return (finfo.type == PR_FILE_DIRECTORY);
}
Ejemplo n.º 9
0
/*
 *  r m _ d a s h _ r
 *
 *  Remove a file, or a directory recursively.
 *
 */
int
rm_dash_r(char *path)
{
    PRDir *dir;
    PRDirEntry *entry;
    PRFileInfo fileinfo;
    char filename[FNSIZE];

    if (PR_GetFileInfo(path, &fileinfo) != PR_SUCCESS) {
        /*fprintf(stderr, "Error: Unable to access %s\n", filename);*/
        return -1;
    }
    if (fileinfo.type == PR_FILE_DIRECTORY) {

        dir = PR_OpenDir(path);
        if (!dir) {
            PR_fprintf(errorFD, "Error: Unable to open directory %s.\n", path);
            errorCount++;
            return -1;
        }

        /* Recursively delete all entries in the directory */
        while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
            sprintf(filename, "%s/%s", path, entry->name);
            if (rm_dash_r(filename))
                return -1;
        }

        if (PR_CloseDir(dir) != PR_SUCCESS) {
            PR_fprintf(errorFD, "Error: Could not close %s.\n", path);
            errorCount++;
            return -1;
        }

        /* Delete the directory itself */
        if (PR_RmDir(path) != PR_SUCCESS) {
            PR_fprintf(errorFD, "Error: Unable to delete %s\n", path);
            errorCount++;
            return -1;
        }
    } else {
        if (PR_Delete(path) != PR_SUCCESS) {
            PR_fprintf(errorFD, "Error: Unable to delete %s\n", path);
            errorCount++;
            return -1;
        }
    }
    return 0;
}
Ejemplo n.º 10
0
Archivo: misc.c Proyecto: leto/389-ds
/*
 * delete the given file/directory and its sub files/directories
 */
int
ldbm_delete_dirs(char *path)
{
    PRDir *dirhandle = NULL;
    PRDirEntry *direntry = NULL;
    char fullpath[MAXPATHLEN];
    int rval = 0;
    PRFileInfo info;

    dirhandle = PR_OpenDir(path);
    if (! dirhandle)
    {
        PR_Delete(path);
        return 0;
    }

    while (NULL != (direntry =
                    PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT)))
    {
        if (! direntry->name)
            break;

        PR_snprintf(fullpath, MAXPATHLEN, "%s/%s", path, direntry->name);
        rval = PR_GetFileInfo(fullpath, &info);
        if (PR_SUCCESS == rval)
        {
            if (PR_FILE_DIRECTORY == info.type)
                rval += ldbm_delete_dirs(fullpath);
        }
        if (PR_FILE_DIRECTORY != info.type)
            PR_Delete(fullpath);
    }
    PR_CloseDir(dirhandle);
    /* remove the directory itself too */
    rval += PR_RmDir(path);
    return rval;
}
Ejemplo n.º 11
0
/*
/////////////////////////////////////////////////////////////////////////
// actually run the installation, copying files to and fro
*/
static Pk11Install_Error
DoInstall(JAR *jar, const char *installDir, const char *tempDir,
          Pk11Install_Platform *platform, PRFileDesc *feedback, PRBool noverify)
{
    Pk11Install_File *file;
    Pk11Install_Error ret;
    char *reldir;
    char *dest;
    char *modDest;
    char *cp;
    int i;
    int status;
    char *tempname, *temp;
    StringList executables;
    StringNode *execNode;
    PRProcessAttr *attr;
    PRProcess *proc;
    char *argv[2];
    char *envp[1];
    int errcode;

    ret = PK11_INSTALL_UNSPECIFIED;
    reldir = NULL;
    dest = NULL;
    modDest = NULL;
    tempname = NULL;

    StringList_new(&executables);
    /*
    // Create Temporary directory
    */
    tempname = PR_smprintf("%s/%s", tempDir, TEMPORARY_DIRECTORY_NAME);
    if (PR_Access(tempname, PR_ACCESS_EXISTS) == PR_SUCCESS) {
        /* Left over from previous run?  Delete it. */
        rm_dash_r(tempname);
    }
    if (PR_MkDir(tempname, 0700) != PR_SUCCESS) {
        error(PK11_INSTALL_CREATE_DIR, tempname);
        ret = PK11_INSTALL_CREATE_DIR;
        goto loser;
    }

    /*
    // Install all the files
    */
    for (i = 0; i < platform->numFiles; i++) {
        file = &platform->files[i];

        if (file->relativePath) {
            PRBool foundMarker = PR_FALSE;
            reldir = PR_Strdup(file->relativePath);

            /* Replace all the markers with the directories for which they stand */
            while (1) {
                if ((cp = PL_strcasestr(reldir, ROOT_MARKER))) {
                    /* Has a %root% marker  */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, installDir,
                                       cp + strlen(ROOT_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else if ((cp = PL_strcasestr(reldir, TEMP_MARKER))) {
                    /* Has a %temp% marker */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, tempname,
                                       cp + strlen(TEMP_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else {
                    break;
                }
            }
            if (!foundMarker) {
                /* Has no markers...this isn't really a relative directory */
                error(PK11_INSTALL_BOGUS_REL_DIR, file->relativePath);
                ret = PK11_INSTALL_BOGUS_REL_DIR;
                goto loser;
            }
            dest = reldir;
            reldir = NULL;
        } else if (file->absolutePath) {
            dest = PR_Strdup(file->absolutePath);
        }

        /* Remember if this is the module file, we'll need to add it later */
        if (i == platform->modFile) {
            modDest = PR_Strdup(dest);
        }

        /* Remember is this is an executable, we'll need to run it later */
        if (file->executable) {
            StringList_Append(&executables, dest);
            /*executables.Append(dest);*/
        }

        /* Make sure the directory we are targetting exists */
        if (make_dirs(dest, file->permissions)) {
            ret = PK11_INSTALL_CREATE_DIR;
            goto loser;
        }

        /* Actually extract the file onto the filesystem */
        if (noverify) {
            status = JAR_extract(jar, (char *)file->jarPath, dest);
        } else {
            status = JAR_verified_extract(jar, (char *)file->jarPath, dest);
        }
        if (status) {
            if (status >= JAR_BASE && status <= JAR_BASE_END) {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      JAR_get_error(status));
            } else {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      mySECU_ErrorString(PORT_GetError()));
            }
            ret = PK11_INSTALL_JAR_EXTRACT;
            goto loser;
        }
        if (feedback) {
            PR_fprintf(feedback, msgStrings[INSTALLED_FILE_MSG],
                       file->jarPath, dest);
        }

/* no NSPR command to change permissions? */
#ifdef XP_UNIX
        chmod(dest, file->permissions);
#endif

        /* Memory clean-up tasks */
        if (reldir) {
            PR_Free(reldir);
            reldir = NULL;
        }
        if (dest) {
            PR_Free(dest);
            dest = NULL;
        }
    }
    /* Make sure we found the module file */
    if (!modDest) {
        /* Internal problem here, since every platform is supposed to have
           a module file */
        error(PK11_INSTALL_NO_MOD_FILE, platform->moduleName);
        ret = PK11_INSTALL_NO_MOD_FILE;
        goto loser;
    }

    /*
    // Execute any executable files
    */
    {
        argv[1] = NULL;
        envp[0] = NULL;
        for (execNode = executables.head; execNode; execNode = execNode->next) {
            attr = PR_NewProcessAttr();
            argv[0] = PR_Strdup(execNode->str);

            /* Announce our intentions */
            if (feedback) {
                PR_fprintf(feedback, msgStrings[EXEC_FILE_MSG], execNode->str);
            }

            /* start the process */
            if (!(proc = PR_CreateProcess(execNode->str, argv, envp, attr))) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_EXEC_FILE, execNode->str);
                ret = PK11_INSTALL_EXEC_FILE;
                goto loser;
            }

            /* wait for it to finish */
            if (PR_WaitProcess(proc, &errcode) != PR_SUCCESS) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_WAIT_PROCESS, execNode->str);
                ret = PK11_INSTALL_WAIT_PROCESS;
                goto loser;
            }

            /* What happened? */
            if (errcode) {
                /* process returned an error */
                error(PK11_INSTALL_PROC_ERROR, execNode->str, errcode);
            } else if (feedback) {
                /* process ran successfully */
                PR_fprintf(feedback, msgStrings[EXEC_SUCCESS], execNode->str);
            }

            PR_Free(argv[0]);
            PR_DestroyProcessAttr(attr);
        }
    }

    /*
    // Add the module
    */
    status = Pk11Install_AddNewModule((char *)platform->moduleName,
                                      (char *)modDest, platform->mechFlags, platform->cipherFlags);

    if (status != SECSuccess) {
        error(PK11_INSTALL_ADD_MODULE, platform->moduleName);
        ret = PK11_INSTALL_ADD_MODULE;
        goto loser;
    }
    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLED_MODULE_MSG],
                   platform->moduleName);
    }

    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLATION_COMPLETE_MSG]);
    }

    ret = PK11_INSTALL_SUCCESS;

loser:
    if (reldir) {
        PR_Free(reldir);
    }
    if (dest) {
        PR_Free(dest);
    }
    if (modDest) {
        PR_Free(modDest);
    }
    if (tempname) {
        PRFileInfo info;
        if (PR_GetFileInfo(tempname, &info) == PR_SUCCESS) {
            if (info.type == PR_FILE_DIRECTORY) {
                /* Recursively remove temporary directory */
                if (rm_dash_r(tempname)) {
                    error(PK11_INSTALL_REMOVE_DIR,
                          tempname);
                    ret = PK11_INSTALL_REMOVE_DIR;
                }
            }
        }
        PR_Free(tempname);
    }
    StringList_delete(&executables);
    return ret;
}
Ejemplo n.º 12
0
int
handle_connection(
    PRFileDesc *tcp_sock,
    PRFileDesc *model_sock,
    int requestCert)
{
    PRFileDesc *ssl_sock = NULL;
    PRFileDesc *local_file_fd = NULL;
    char *pBuf; /* unused space at end of buf */
    const char *errString;
    PRStatus status;
    int bufRem;    /* unused bytes at end of buf */
    int bufDat;    /* characters received in buf */
    int newln = 0; /* # of consecutive newlns */
    int firstTime = 1;
    int reqLen;
    int rv;
    int numIOVs;
    PRSocketOptionData opt;
    PRIOVec iovs[16];
    char msgBuf[160];
    char buf[10240];
    char fileName[513];
    char *getData = NULL; /* inplace conversion */
    SECItem postData;
    PRBool isOcspRequest = PR_FALSE;
    PRBool isPost;

    postData.data = NULL;
    postData.len = 0;

    pBuf = buf;
    bufRem = sizeof buf;

    VLOG(("httpserv: handle_connection: starting"));
    opt.option = PR_SockOpt_Nonblocking;
    opt.value.non_blocking = PR_FALSE;
    PR_SetSocketOption(tcp_sock, &opt);

    VLOG(("httpserv: handle_connection: starting\n"));
    ssl_sock = tcp_sock;

    if (noDelay) {
        opt.option = PR_SockOpt_NoDelay;
        opt.value.no_delay = PR_TRUE;
        status = PR_SetSocketOption(ssl_sock, &opt);
        if (status != PR_SUCCESS) {
            errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)");
            if (ssl_sock) {
                PR_Close(ssl_sock);
            }
            return SECFailure;
        }
    }

    while (1) {
        const char *post;
        const char *foundStr = NULL;
        const char *tmp = NULL;

        newln = 0;
        reqLen = 0;

        rv = PR_Read(ssl_sock, pBuf, bufRem - 1);
        if (rv == 0 ||
            (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) {
            if (verbose)
                errWarn("HDX PR_Read hit EOF");
            break;
        }
        if (rv < 0) {
            errWarn("HDX PR_Read");
            goto cleanup;
        }
        /* NULL termination */
        pBuf[rv] = 0;
        if (firstTime) {
            firstTime = 0;
        }

        pBuf += rv;
        bufRem -= rv;
        bufDat = pBuf - buf;
        /* Parse the input, starting at the beginning of the buffer.
         * Stop when we detect two consecutive \n's (or \r\n's)
         * as this signifies the end of the GET or POST portion.
         * The posted data follows.
         */
        while (reqLen < bufDat && newln < 2) {
            int octet = buf[reqLen++];
            if (octet == '\n') {
                newln++;
            } else if (octet != '\r') {
                newln = 0;
            }
        }

        /* came to the end of the buffer, or second newln
         * If we didn't get an empty line (CRLFCRLF) then keep on reading.
         */
        if (newln < 2)
            continue;

        /* we're at the end of the HTTP request.
         * If the request is a POST, then there will be one more
         * line of data.
         * This parsing is a hack, but ok for SSL test purposes.
         */
        post = PORT_Strstr(buf, "POST ");
        if (!post || *post != 'P')
            break;

        postData.data = (void *)(buf + reqLen);

        tmp = "content-length: ";
        foundStr = PL_strcasestr(buf, tmp);
        if (foundStr) {
            int expectedPostLen;
            int havePostLen;

            expectedPostLen = atoi(foundStr + strlen(tmp));
            havePostLen = bufDat - reqLen;
            if (havePostLen >= expectedPostLen) {
                postData.len = expectedPostLen;
                break;
            }
        } else {
            /* use legacy hack */
            /* It's a post, so look for the next and final CR/LF. */
            while (reqLen < bufDat && newln < 3) {
                int octet = buf[reqLen++];
                if (octet == '\n') {
                    newln++;
                }
            }
            if (newln == 3)
                break;
        }
    } /* read loop */

    bufDat = pBuf - buf;
    if (bufDat)
        do { /* just close if no data */
            /* Have either (a) a complete get, (b) a complete post, (c) EOF */
            if (reqLen > 0) {
                PRBool isGetOrPost = PR_FALSE;
                unsigned skipChars = 0;
                isPost = PR_FALSE;

                if (!strncmp(buf, getCmd, sizeof getCmd - 1)) {
                    isGetOrPost = PR_TRUE;
                    skipChars = 4;
                } else if (!strncmp(buf, "POST ", 5)) {
                    isGetOrPost = PR_TRUE;
                    isPost = PR_TRUE;
                    skipChars = 5;
                }

                if (isGetOrPost) {
                    char *fnBegin = buf;
                    char *fnEnd;
                    char *fnstart = NULL;
                    PRFileInfo info;

                    fnBegin += skipChars;

                    fnEnd = strpbrk(fnBegin, " \r\n");
                    if (fnEnd) {
                        int fnLen = fnEnd - fnBegin;
                        if (fnLen < sizeof fileName) {
                            strncpy(fileName, fnBegin, fnLen);
                            fileName[fnLen] = 0; /* null terminate */
                            fnstart = fileName;
                            /* strip initial / because our root is the current directory*/
                            while (*fnstart && *fnstart == '/')
                                ++fnstart;
                        }
                    }
                    if (fnstart) {
                        if (!strncmp(fnstart, "ocsp", 4)) {
                            if (isPost) {
                                if (postData.data) {
                                    isOcspRequest = PR_TRUE;
                                }
                            } else {
                                if (!strncmp(fnstart, "ocsp/", 5)) {
                                    isOcspRequest = PR_TRUE;
                                    getData = fnstart + 5;
                                }
                            }
                        } else {
                            /* try to open the file named.
                             * If successful, then write it to the client.
                             */
                            status = PR_GetFileInfo(fnstart, &info);
                            if (status == PR_SUCCESS &&
                                info.type == PR_FILE_FILE &&
                                info.size >= 0) {
                                local_file_fd = PR_Open(fnstart, PR_RDONLY, 0);
                            }
                        }
                    }
                }
            }

            numIOVs = 0;

            iovs[numIOVs].iov_base = (char *)outHeader;
            iovs[numIOVs].iov_len = (sizeof(outHeader)) - 1;
            numIOVs++;

            if (isOcspRequest && caRevoInfos) {
                CERTOCSPRequest *request = NULL;
                PRBool failThisRequest = PR_FALSE;
                PLArenaPool *arena = NULL;

                if (ocspMethodsAllowed == ocspGetOnly && postData.len) {
                    failThisRequest = PR_TRUE;
                } else if (ocspMethodsAllowed == ocspPostOnly && getData) {
                    failThisRequest = PR_TRUE;
                } else if (ocspMethodsAllowed == ocspRandomGetFailure && getData) {
                    if (!(rand() % 2)) {
                        failThisRequest = PR_TRUE;
                    }
                }

                if (failThisRequest) {
                    PR_Write(ssl_sock, outBadRequestHeader, strlen(outBadRequestHeader));
                    break;
                }
                /* get is base64, post is binary.
                 * If we have base64, convert into the (empty) postData array.
                 */
                if (getData) {
                    if (urldecode_base64chars_inplace(getData) == SECSuccess) {
                        /* The code below can handle a NULL arena */
                        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
                        NSSBase64_DecodeBuffer(arena, &postData, getData, strlen(getData));
                    }
                }
                if (postData.len) {
                    request = CERT_DecodeOCSPRequest(&postData);
                }
                if (arena) {
                    PORT_FreeArena(arena, PR_FALSE);
                }
                if (!request || !request->tbsRequest ||
                    !request->tbsRequest->requestList ||
                    !request->tbsRequest->requestList[0]) {
                    PORT_Sprintf(msgBuf, "Cannot decode OCSP request.\r\n");

                    iovs[numIOVs].iov_base = msgBuf;
                    iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                    numIOVs++;
                } else {
                    /* TODO: support more than one request entry */
                    CERTOCSPCertID *reqid = request->tbsRequest->requestList[0]->reqCert;
                    const caRevoInfo *revoInfo = NULL;
                    PRBool unknown = PR_FALSE;
                    PRBool revoked = PR_FALSE;
                    PRTime nextUpdate = 0;
                    PRTime revoDate = 0;
                    PRCList *caRevoIter;

                    caRevoIter = &caRevoInfos->link;
                    do {
                        CERTOCSPCertID *caid;

                        revoInfo = (caRevoInfo *)caRevoIter;
                        caid = revoInfo->id;

                        if (SECOID_CompareAlgorithmID(&reqid->hashAlgorithm,
                                                      &caid->hashAlgorithm) == SECEqual &&
                            SECITEM_CompareItem(&reqid->issuerNameHash,
                                                &caid->issuerNameHash) == SECEqual &&
                            SECITEM_CompareItem(&reqid->issuerKeyHash,
                                                &caid->issuerKeyHash) == SECEqual) {
                            break;
                        }
                        revoInfo = NULL;
                        caRevoIter = PR_NEXT_LINK(caRevoIter);
                    } while (caRevoIter != &caRevoInfos->link);

                    if (!revoInfo) {
                        unknown = PR_TRUE;
                        revoInfo = caRevoInfos;
                    } else {
                        CERTCrl *crl = &revoInfo->crl->crl;
                        CERTCrlEntry *entry = NULL;
                        DER_DecodeTimeChoice(&nextUpdate, &crl->nextUpdate);
                        if (crl->entries) {
                            int iv = 0;
                            /* assign, not compare */
                            while ((entry = crl->entries[iv++])) {
                                if (SECITEM_CompareItem(&reqid->serialNumber,
                                                        &entry->serialNumber) == SECEqual) {
                                    break;
                                }
                            }
                        }
                        if (entry) {
                            /* revoked status response */
                            revoked = PR_TRUE;
                            DER_DecodeTimeChoice(&revoDate, &entry->revocationDate);
                        } else {
                            /* else good status response */
                            if (!isPost && ocspMethodsAllowed == ocspGetUnknown) {
                                unknown = PR_TRUE;
                                nextUpdate = PR_Now() + (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /*tomorrow*/
                                revoDate = PR_Now() - (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC;   /*yesterday*/
                            }
                        }
                    }

                    {
                        PRTime now = PR_Now();
                        PLArenaPool *arena = NULL;
                        CERTOCSPSingleResponse *sr;
                        CERTOCSPSingleResponse **singleResponses;
                        SECItem *ocspResponse;

                        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

                        if (unknown) {
                            sr = CERT_CreateOCSPSingleResponseUnknown(arena, reqid, now,
                                                                      &nextUpdate);
                        } else if (revoked) {
                            sr = CERT_CreateOCSPSingleResponseRevoked(arena, reqid, now,
                                                                      &nextUpdate, revoDate, NULL);
                        } else {
                            sr = CERT_CreateOCSPSingleResponseGood(arena, reqid, now,
                                                                   &nextUpdate);
                        }

                        /* meaning of value 2: one entry + one end marker */
                        singleResponses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse *, 2);
                        singleResponses[0] = sr;
                        singleResponses[1] = NULL;
                        ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena,
                                                                             revoInfo->cert, ocspResponderID_byName, now,
                                                                             singleResponses, &pwdata);

                        if (!ocspResponse) {
                            PORT_Sprintf(msgBuf, "Failed to encode response\r\n");
                            iovs[numIOVs].iov_base = msgBuf;
                            iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                            numIOVs++;
                        } else {
                            PR_Write(ssl_sock, outOcspHeader, strlen(outOcspHeader));
                            PR_Write(ssl_sock, ocspResponse->data, ocspResponse->len);
                            PORT_FreeArena(arena, PR_FALSE);
                        }
                    }
                    CERT_DestroyOCSPRequest(request);
                    break;
                }
            } else if (local_file_fd) {
                PRInt32 bytes;
                int errLen;
                bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader,
                                        sizeof outHeader - 1,
                                        PR_TRANSMITFILE_KEEP_OPEN,
                                        PR_INTERVAL_NO_TIMEOUT);
                if (bytes >= 0) {
                    bytes -= sizeof outHeader - 1;
                    FPRINTF(stderr,
                            "httpserv: PR_TransmitFile wrote %d bytes from %s\n",
                            bytes, fileName);
                    break;
                }
                errString = errWarn("PR_TransmitFile");
                errLen = PORT_Strlen(errString);
                errLen = PR_MIN(errLen, sizeof msgBuf - 1);
                PORT_Memcpy(msgBuf, errString, errLen);
                msgBuf[errLen] = 0;

                iovs[numIOVs].iov_base = msgBuf;
                iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                numIOVs++;
            } else if (reqLen <= 0) { /* hit eof */
                PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n",
                             bufDat);

                iovs[numIOVs].iov_base = msgBuf;
                iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                numIOVs++;
            } else if (reqLen < bufDat) {
                PORT_Sprintf(msgBuf, "Discarded %d characters.\r\n",
                             bufDat - reqLen);

                iovs[numIOVs].iov_base = msgBuf;
                iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                numIOVs++;
            }

            if (reqLen > 0) {
                if (verbose > 1)
                    fwrite(buf, 1, reqLen, stdout); /* display it */

                iovs[numIOVs].iov_base = buf;
                iovs[numIOVs].iov_len = reqLen;
                numIOVs++;
            }

            rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT);
            if (rv < 0) {
                errWarn("PR_Writev");
                break;
            }

        } while (0);
Ejemplo n.º 13
0
Archivo: config.c Proyecto: leto/389-ds
/*
  Extract just the configuration information we need for bootstrapping
  purposes
  1) set up error logging
  2) disable syntax checking
  3) load the syntax plugins
  etc.
*/
int
slapd_bootstrap_config(const char *configdir)
{
	char configfile[MAXPATHLEN+1];
    PRFileInfo prfinfo;
    int rc = 0; /* Fail */
	int done = 0;
    PRInt32 nr = 0;
	PRFileDesc *prfd = 0;
	char *buf = 0;
	char *lastp = 0;
	char *entrystr = 0;

	if (NULL == configdir) {
		slapi_log_error(SLAPI_LOG_FATAL,
						"startup", "Passed null config directory\n");
		return rc; /* Fail */
	}
	PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir,
				CONFIG_FILENAME);
	if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS )
	{
		/* the "real" file does not exist; see if there is a tmpfile */
		char tmpfile[MAXPATHLEN+1];
		slapi_log_error(SLAPI_LOG_FATAL, "config",
					"The configuration file %s does not exist\n", configfile);
		PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.tmp", configdir,
					CONFIG_FILENAME);
		if ( PR_GetFileInfo( tmpfile, &prfinfo ) == PR_SUCCESS ) {
			rc = PR_Rename(tmpfile, configfile);
			if (rc == PR_SUCCESS) {
				slapi_log_error(SLAPI_LOG_FATAL, "config",
								"The configuration file %s was restored from backup %s\n",
								configfile, tmpfile);
			} else {
				slapi_log_error(SLAPI_LOG_FATAL, "config",
								"The configuration file %s was not restored from backup %s, error %d\n",
								configfile, tmpfile, rc);
				return rc; /* Fail */
			}
		} else {
			slapi_log_error(SLAPI_LOG_FATAL, "config",
				"The backup configuration file %s does not exist, either.\n",
				tmpfile);
			return rc; /* Fail */
		}
	}
	if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS )
	{
		PRErrorCode prerr = PR_GetError();
		slapi_log_error(SLAPI_LOG_FATAL, "config", "The given config file %s could not be accessed, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
						configfile, prerr, slapd_pr_strerror(prerr));
		return rc;
	}
	else if (( prfd = PR_Open( configfile, PR_RDONLY,
							   SLAPD_DEFAULT_FILE_MODE )) == NULL )
	{
		PRErrorCode prerr = PR_GetError();
		slapi_log_error(SLAPI_LOG_FATAL, "config", "The given config file %s could not be opened for reading, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
						configfile, prerr, slapd_pr_strerror(prerr));
		return rc; /* Fail */
	}
	else
	{
		/* read the entire file into core */
		buf = slapi_ch_malloc( prfinfo.size + 1 );
		if (( nr = slapi_read_buffer( prfd, buf, prfinfo.size )) < 0 )
		{
			slapi_log_error(SLAPI_LOG_FATAL, "config", "Could only read %d of %d bytes from config file %s\n",
							nr, prfinfo.size, configfile);
			rc = 0; /* Fail */
			done= 1;
		}
                          
		(void)PR_Close(prfd);
		buf[ nr ] = '\0';

		if(!done)
		{
			char workpath[MAXPATHLEN+1];
			char loglevel[BUFSIZ];
			char maxdescriptors[BUFSIZ];
			char val[BUFSIZ];
			char _localuser[BUFSIZ];
			char logenabled[BUFSIZ];
			char schemacheck[BUFSIZ];
			char syntaxcheck[BUFSIZ];
			char syntaxlogging[BUFSIZ];
			char plugintracking[BUFSIZ];
			char dn_validate_strict[BUFSIZ];
			Slapi_DN plug_dn;

			workpath[0] = loglevel[0] = maxdescriptors[0] = '\0';
			val[0] = logenabled[0] = schemacheck[0] = syntaxcheck[0] = '\0';
			syntaxlogging[0] = _localuser[0] = '\0';
			plugintracking [0] = dn_validate_strict[0] = '\0';

			/* Convert LDIF to entry structures */
			slapi_sdn_init_ndn_byref(&plug_dn, PLUGIN_BASE_DN);
			while ((entrystr = dse_read_next_entry(buf, &lastp)) != NULL)
			{
				char errorbuf[BUFSIZ];
				/*
				 * XXXmcs: it would be better to also pass
				 * SLAPI_STR2ENTRY_REMOVEDUPVALS in the flags, but
				 * duplicate value checking requires that the syntax
				 * and schema subsystems be initialized... and they
				 * are not yet.
				 */
				Slapi_Entry	*e = slapi_str2entry(entrystr,
							SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
				if (e == NULL)
				{
					  LDAPDebug(LDAP_DEBUG_ANY, "The entry [%s] in the configfile %s was empty or could not be parsed\n",
								entrystr, configfile, 0);
					continue;
				}
				/* increase file descriptors */
#if !defined(_WIN32) && !defined(AIX)
				if (!maxdescriptors[0] &&
					entry_has_attr_and_value(e, CONFIG_MAXDESCRIPTORS_ATTRIBUTE,
									 maxdescriptors, sizeof(maxdescriptors)))
				{
					if (config_set_maxdescriptors(
									CONFIG_MAXDESCRIPTORS_ATTRIBUTE,
									maxdescriptors, errorbuf, CONFIG_APPLY)
						!= LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_MAXDESCRIPTORS_ATTRIBUTE, errorbuf);
					}
				}
#endif /* !defined(_WIN32) && !defined(AIX) */

				/* see if we need to enable error logging */
				if (!logenabled[0] &&
					entry_has_attr_and_value(e,
											 CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE,
											 logenabled, sizeof(logenabled)))
				{
					if (log_set_logging(
						CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE,
						logenabled, SLAPD_ERROR_LOG, errorbuf, CONFIG_APPLY)
						!= LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, errorbuf);
					}
				}

#ifndef _WIN32
				/* set the local user name; needed to set up error log */
				if (!_localuser[0] &&
					entry_has_attr_and_value(e, CONFIG_LOCALUSER_ATTRIBUTE,
								_localuser, sizeof(_localuser)))
				{
					if (config_set_localuser(CONFIG_LOCALUSER_ATTRIBUTE,
						_localuser, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile,
								  CONFIG_LOCALUSER_ATTRIBUTE, errorbuf);
					}
				}
#endif
				
				/* set the log file name */
				workpath[0] = '\0';
				if (!workpath[0] &&
					entry_has_attr_and_value(e, CONFIG_ERRORLOG_ATTRIBUTE,
								workpath, sizeof(workpath)))
				{
					if (config_set_errorlog(CONFIG_ERRORLOG_ATTRIBUTE,
						workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile,
								  CONFIG_ERRORLOG_ATTRIBUTE, errorbuf);
					}
				}
				/* set the error log level */
				if (!loglevel[0] &&
					entry_has_attr_and_value(e, CONFIG_LOGLEVEL_ATTRIBUTE,
						loglevel, sizeof(loglevel)))
				{
					if (should_detach || !config_get_errorlog_level())
					{ /* -d wasn't on command line */
						if (config_set_errorlog_level(CONFIG_LOGLEVEL_ATTRIBUTE,
							loglevel, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
						{
							LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile,
									  CONFIG_LOGLEVEL_ATTRIBUTE, errorbuf);
						}
					}
					else
					{
						LDAPDebug(LDAP_DEBUG_ANY,
								  "%s: ignoring %s (since -d %d was given on "
								  "the command line)\n",
								  CONFIG_LOGLEVEL_ATTRIBUTE, loglevel,
								  config_get_errorlog_level());
					}
				}

				/* set the cert dir; needed in slapd_nss_init */
				workpath[0] = '\0';
				if (entry_has_attr_and_value(e, CONFIG_CERTDIR_ATTRIBUTE,
						workpath, sizeof(workpath)))
				{
					if (config_set_certdir(CONFIG_CERTDIR_ATTRIBUTE,
							workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile,
									  CONFIG_CERTDIR_ATTRIBUTE, errorbuf);
					}
				}

				/* set the sasl path; needed in main */
				 workpath[0] = '\0';
				if (entry_has_attr_and_value(e, CONFIG_SASLPATH_ATTRIBUTE,
						workpath, sizeof(workpath)))
				{
					if (config_set_saslpath(CONFIG_SASLPATH_ATTRIBUTE,
							workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile,
									  CONFIG_SASLPATH_ATTRIBUTE, errorbuf);
					}
				}
#if defined(ENABLE_LDAPI)
				/* set the ldapi file path; needed in main */
				workpath[0] = '\0';
				if (entry_has_attr_and_value(e, CONFIG_LDAPI_FILENAME_ATTRIBUTE,
						workpath, sizeof(workpath)))
				{
					if (config_set_ldapi_filename(CONFIG_LDAPI_FILENAME_ATTRIBUTE,
							workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile,
									  CONFIG_LDAPI_FILENAME_ATTRIBUTE, errorbuf);
					}
				}

				/* set the ldapi switch; needed in main */
				workpath[0] = '\0';
				if (entry_has_attr_and_value(e, CONFIG_LDAPI_SWITCH_ATTRIBUTE,
						workpath, sizeof(workpath)))
				{
					if (config_set_ldapi_switch(CONFIG_LDAPI_SWITCH_ATTRIBUTE,
							workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile,
									  CONFIG_LDAPI_SWITCH_ATTRIBUTE, errorbuf);
					}
				}
#endif
				/* see if the entry is a child of the plugin base dn */
				if (slapi_sdn_isparent(&plug_dn,
									   slapi_entry_get_sdn_const(e)))
				{
					if (entry_has_attr_and_value(e, "objectclass",
												 "nsSlapdPlugin", 0) &&
						(entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE,
												 "syntax", 0) ||
						 entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE,
												  "matchingrule", 0)))
					{
						/* add the syntax/matching scheme rule plugin */
						if (plugin_setup(e, 0, 0, 1))
						{
							LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was invalid\n", slapi_entry_get_dn(e), configfile, 0);
							rc = 0;
							slapi_sdn_done(&plug_dn);
							goto bail;
						}
					}
				}

				/* see if the entry is a grand child of the plugin base dn */
				if (slapi_sdn_isgrandparent(&plug_dn,
											slapi_entry_get_sdn_const(e)))
				{
					if (entry_has_attr_and_value(e, "objectclass",
												 "nsSlapdPlugin", 0) &&
						(	entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE,
												"pwdstoragescheme", 0) ||
							entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE,
												"reverpwdstoragescheme", 0)	) )
					{
						/* add the pwd storage scheme rule plugin */
						if (plugin_setup(e, 0, 0, 1))
						{
							LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was invalid\n", slapi_entry_get_dn(e), configfile, 0);
							rc = 0;
							slapi_sdn_done(&plug_dn);
							goto bail;
						}
					}
				}

				/* see if we need to disable schema checking */
				if (!schemacheck[0] &&
					entry_has_attr_and_value(e, CONFIG_SCHEMACHECK_ATTRIBUTE,
											 schemacheck, sizeof(schemacheck)))
				{
					if (config_set_schemacheck(CONFIG_SCHEMACHECK_ATTRIBUTE,
								schemacheck, errorbuf, CONFIG_APPLY)
								!= LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_SCHEMACHECK_ATTRIBUTE, errorbuf);
					}
				}

				/* see if we need to enable plugin binddn tracking */
				if (!plugintracking[0] &&
					entry_has_attr_and_value(e, CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE,
											 plugintracking, sizeof(plugintracking)))
				{
					if (config_set_plugin_tracking(CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE,
							plugintracking, errorbuf, CONFIG_APPLY)
								!= LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, errorbuf);
					}
				}

				/* see if we need to enable syntax checking */
				if (!syntaxcheck[0] &&
				    entry_has_attr_and_value(e, CONFIG_SYNTAXCHECK_ATTRIBUTE,
				    syntaxcheck, sizeof(syntaxcheck)))
				{
					if (config_set_syntaxcheck(CONFIG_SYNTAXCHECK_ATTRIBUTE,
					                           syntaxcheck, errorbuf, CONFIG_APPLY)
						                   != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
						          CONFIG_SYNTAXCHECK_ATTRIBUTE, errorbuf);
					}
				}

				/* see if we need to enable syntax warnings */
				if (!syntaxlogging[0] &&
				    entry_has_attr_and_value(e, CONFIG_SYNTAXLOGGING_ATTRIBUTE,
				    syntaxlogging, sizeof(syntaxlogging)))
				{
					if (config_set_syntaxlogging(CONFIG_SYNTAXLOGGING_ATTRIBUTE,
					                          syntaxlogging, errorbuf, CONFIG_APPLY)
					                          != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
						          CONFIG_SYNTAXLOGGING_ATTRIBUTE, errorbuf);
					}
				}

				/* see if we need to enable strict dn validation */
				if (!dn_validate_strict[0] &&
				    entry_has_attr_and_value(e, CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE,
				    dn_validate_strict, sizeof(dn_validate_strict)))
				{
					if (config_set_dn_validate_strict(CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE,
					                           dn_validate_strict, errorbuf, CONFIG_APPLY)
					                           != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
						          CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, errorbuf);
					}
				}

				/* see if we need to expect quoted schema values */
				if (entry_has_attr_and_value(e, CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE,
											 val, sizeof(val)))
				{
					if (config_set_enquote_sup_oc(
								CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, val, errorbuf, 
								CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, errorbuf);
					}
					val[0] = 0;
				}

				/* see if we need to maintain case in AT and OC names */
				if (entry_has_attr_and_value(e,
						CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, val, sizeof(val)))
				{
					if (config_set_return_exact_case(
								CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, val,
								errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, errorbuf);
					}
					val[0] = 0;
				}

				/* see if we should allow attr. name exceptions, e.g. '_'s */
				if (entry_has_attr_and_value(e,
						CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE,
						val, sizeof(val)))
				{
					if (config_set_attrname_exceptions(
								CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, val,
								errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE,
								  errorbuf);
					}
					val[0] = 0;
				}

				/* see if we need to maintain schema compatibility with 4.x */
				if (entry_has_attr_and_value(e,
						CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, val, sizeof(val)))
				{
					if (config_set_ds4_compatible_schema(
								CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, val,
								errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE,
								  errorbuf);
					}
					val[0] = 0;
				}

				/* see if we need to allow trailing spaces in OC and AT names */
				if (entry_has_attr_and_value(e,
						CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, val, sizeof(val)))
				{
					if (config_set_schema_ignore_trailing_spaces(
								CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, val,
								errorbuf, CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_SCHEMA_IGNORE_TRAILING_SPACES,
								  errorbuf);
					}
					val[0] = 0;
				}

				/* rfc1274-rewrite */
				if (entry_has_attr_and_value(e, 
							     CONFIG_REWRITE_RFC1274_ATTRIBUTE,
							     val, sizeof(val))) {
				  if (config_set_rewrite_rfc1274(
								 CONFIG_REWRITE_RFC1274_ATTRIBUTE, val, 
								 errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) {
				    LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", 
					      configfile,
					      CONFIG_REWRITE_RFC1274_ATTRIBUTE, 
					      errorbuf);
				  }
				  val[0] = 0;
				}

				/* what is our localhost name */
				if (entry_has_attr_and_value(e, CONFIG_LOCALHOST_ATTRIBUTE,
											 val, sizeof(val)))
				{
					if (config_set_localhost(
								CONFIG_LOCALHOST_ATTRIBUTE, val, errorbuf, 
								CONFIG_APPLY) != LDAP_SUCCESS)
					{
						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
								  CONFIG_LOCALHOST_ATTRIBUTE, errorbuf);
					}
					val[0] = 0;
				}

				if (e)
					slapi_entry_free(e);
			}
			/* kexcoff: initialize rootpwstoragescheme and pw_storagescheme
			 *			if not explicilty set in the config file
			 */
			if ( config_set_storagescheme() ) {		/* default scheme plugin not loaded */
				slapi_log_error(SLAPI_LOG_FATAL, "startup",
								"The default password storage scheme SSHA could not be read or was not found in the file %s. It is mandatory.\n",
								configfile);
				exit (1);
			}
			else {
				slapi_sdn_done(&plug_dn);
				rc= 1; /* OK */
			}
		}

		slapi_ch_free_string(&buf);
	}

bail:
	slapi_ch_free_string(&buf);
	return rc;
}
Ejemplo n.º 14
0
int
handle_connection( 
    PRFileDesc *tcp_sock,
    PRFileDesc *model_sock,
    int         requestCert
    )
{
    PRFileDesc *       ssl_sock = NULL;
    PRFileDesc *       local_file_fd = NULL;
    char  *            post;
    char  *            pBuf;			/* unused space at end of buf */
    const char *       errString;
    PRStatus           status;
    int                bufRem;			/* unused bytes at end of buf */
    int                bufDat;			/* characters received in buf */
    int                newln    = 0;		/* # of consecutive newlns */
    int                firstTime = 1;
    int                reqLen;
    int                rv;
    int                numIOVs;
    PRSocketOptionData opt;
    PRIOVec            iovs[16];
    char               msgBuf[160];
    char               buf[10240];
    char               fileName[513];

    pBuf   = buf;
    bufRem = sizeof buf;

    VLOG(("selfserv: handle_connection: starting"));
    opt.option             = PR_SockOpt_Nonblocking;
    opt.value.non_blocking = PR_FALSE;
    PR_SetSocketOption(tcp_sock, &opt);

    VLOG(("selfserv: handle_connection: starting\n"));
	ssl_sock = tcp_sock;

    if (noDelay) {
	opt.option         = PR_SockOpt_NoDelay;
	opt.value.no_delay = PR_TRUE;
	status = PR_SetSocketOption(ssl_sock, &opt);
	if (status != PR_SUCCESS) {
	    errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)");
            if (ssl_sock) {
	        PR_Close(ssl_sock);
            }
	    return SECFailure;
	}
    }

    while (1) {
	newln = 0;
	reqLen     = 0;
	rv = PR_Read(ssl_sock, pBuf, bufRem - 1);
	if (rv == 0 || 
	    (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) {
	    if (verbose)
		errWarn("HDX PR_Read hit EOF");
	    break;
	}
	if (rv < 0) {
	    errWarn("HDX PR_Read");
	    goto cleanup;
	}
	/* NULL termination */
	pBuf[rv] = 0;
	if (firstTime) {
	    firstTime = 0;
	}

	pBuf   += rv;
	bufRem -= rv;
	bufDat = pBuf - buf;
	/* Parse the input, starting at the beginning of the buffer.
	 * Stop when we detect two consecutive \n's (or \r\n's) 
	 * as this signifies the end of the GET or POST portion.
	 * The posted data follows.
	 */
	while (reqLen < bufDat && newln < 2) {
	    int octet = buf[reqLen++];
	    if (octet == '\n') {
		newln++;
	    } else if (octet != '\r') {
		newln = 0;
	    }
	}

	/* came to the end of the buffer, or second newln
	 * If we didn't get an empty line (CRLFCRLF) then keep on reading.
	 */
	if (newln < 2) 
	    continue;

	/* we're at the end of the HTTP request.
	 * If the request is a POST, then there will be one more
	 * line of data.
	 * This parsing is a hack, but ok for SSL test purposes.
	 */
	post = PORT_Strstr(buf, "POST ");
	if (!post || *post != 'P') 
	    break;

	/* It's a post, so look for the next and final CR/LF. */
	/* We should parse content length here, but ... */
	while (reqLen < bufDat && newln < 3) {
	    int octet = buf[reqLen++];
	    if (octet == '\n') {
		newln++;
	    }
	}
	if (newln == 3)
	    break;
    } /* read loop */

    bufDat = pBuf - buf;
    if (bufDat) do {	/* just close if no data */
	/* Have either (a) a complete get, (b) a complete post, (c) EOF */
	if (reqLen > 0 && !strncmp(buf, getCmd, sizeof getCmd - 1)) {
	    char *      fnBegin = buf + 4;
	    char *      fnEnd;
	    PRFileInfo  info;
	    /* try to open the file named.  
	     * If successful, then write it to the client.
	     */
	    fnEnd = strpbrk(fnBegin, " \r\n");
	    if (fnEnd) {
		int fnLen = fnEnd - fnBegin;
		if (fnLen < sizeof fileName) {
                    char *fnstart;
                    strncpy(fileName, fnBegin, fnLen);
                    fileName[fnLen] = 0;	/* null terminate */
                    fnstart = fileName;
                    /* strip initial / because our root is the current directory*/
                    while (*fnstart && *fnstart=='/')
                        ++fnstart;
		    status = PR_GetFileInfo(fnstart, &info);
		    if (status == PR_SUCCESS &&
			info.type == PR_FILE_FILE &&
			info.size >= 0 ) {
			local_file_fd = PR_Open(fnstart, PR_RDONLY, 0);
		    }
		}
	    }
	}

	numIOVs = 0;

	iovs[numIOVs].iov_base = (char *)outHeader;
	iovs[numIOVs].iov_len  = (sizeof(outHeader)) - 1;
	numIOVs++;

	if (local_file_fd) {
	    PRInt32     bytes;
	    int         errLen;
            bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader,
                                    sizeof outHeader - 1,
                                    PR_TRANSMITFILE_KEEP_OPEN,
                                    PR_INTERVAL_NO_TIMEOUT);
            if (bytes >= 0) {
                bytes -= sizeof outHeader - 1;
                FPRINTF(stderr, 
                        "selfserv: PR_TransmitFile wrote %d bytes from %s\n",
                        bytes, fileName);
                break;
            }
            errString = errWarn("PR_TransmitFile");
            errLen = PORT_Strlen(errString);
            errLen = PR_MIN(errLen, sizeof msgBuf - 1);
            PORT_Memcpy(msgBuf, errString, errLen);
            msgBuf[errLen] = 0;
            
            iovs[numIOVs].iov_base = msgBuf;
            iovs[numIOVs].iov_len  = PORT_Strlen(msgBuf);
            numIOVs++;
	} else if (reqLen <= 0) {	/* hit eof */
	    PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n",
			 bufDat);

	    iovs[numIOVs].iov_base = msgBuf;
	    iovs[numIOVs].iov_len  = PORT_Strlen(msgBuf);
	    numIOVs++;
	} else if (reqLen < bufDat) {
	    PORT_Sprintf(msgBuf, "Discarded %d characters.\r\n", 
	                 bufDat - reqLen);

	    iovs[numIOVs].iov_base = msgBuf;
	    iovs[numIOVs].iov_len  = PORT_Strlen(msgBuf);
	    numIOVs++;
	}

	if (reqLen > 0) {
	    if (verbose > 1) 
	    	fwrite(buf, 1, reqLen, stdout);	/* display it */

	    iovs[numIOVs].iov_base = buf;
	    iovs[numIOVs].iov_len  = reqLen;
	    numIOVs++;
	}

        /* Don't add the EOF if we want to test bulk encryption */
        if (!testBulk) {
            iovs[numIOVs].iov_base = (char *)EOFmsg;
            iovs[numIOVs].iov_len  = sizeof EOFmsg - 1;
            numIOVs++;
        }

	rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT);
	if (rv < 0) {
	    errWarn("PR_Writev");
	    break;
	}

    } while (0);

cleanup:
    if (ssl_sock) {
        PR_Close(ssl_sock);
    } else if (tcp_sock) {
        PR_Close(tcp_sock);
    }
    if (local_file_fd)
	PR_Close(local_file_fd);
    VLOG(("selfserv: handle_connection: exiting\n"));

    /* do a nice shutdown if asked. */
    if (!strncmp(buf, stopCmd, sizeof stopCmd - 1)) {
        VLOG(("selfserv: handle_connection: stop command"));
        stop_server();
    }
    VLOG(("selfserv: handle_connection: exiting"));
    return SECSuccess;	/* success */
}
static SECStatus
handle_connection(PRFileDesc *sslSocket)
{
#if DEBUG
  int	      countRead = 0;
#endif
  PRInt32     numBytes;
  char       *readBuffer;
  PRFileInfo  info;
  PRFileDesc *local_file_fd;
  PRStatus    prStatus;
  SECStatus   secStatus = SECSuccess;

  /* read and send the data. */
  /* Try to open the local file named.	
   * If successful, then write it to the server
   */
  prStatus = PR_GetFileInfo(infileName, &info);
  if (prStatus != PR_SUCCESS ||
      info.type != PR_FILE_FILE ||
      info.size < 0)
    {
      fprintf (stderr, "could not find input file %s\n", infileName);
      return SECFailure;
    }

  local_file_fd = PR_Open(infileName, PR_RDONLY, 0);
  if (local_file_fd == NULL)
    {
      fprintf (stderr, "could not open input file %s\n", infileName);
      return SECFailure;
    }

  /* Send the file size first, so the server knows when it has the entire file. */
  numBytes = PR_Write(sslSocket, & info.size, sizeof (info.size));
  if (numBytes < 0)
    return SECFailure;

  /* Transmit the local file across the socket.  */
  numBytes = PR_TransmitFile(sslSocket, local_file_fd, 
			     NULL, 0,
			     PR_TRANSMITFILE_KEEP_OPEN,
			     PR_INTERVAL_NO_TIMEOUT);
  if (numBytes < 0)
    return SECFailure;

#if DEBUG
  /* Transmitted bytes successfully. */
  fprintf(stderr, "PR_TransmitFile wrote %d bytes from %s\n",
	  numBytes, infileName);
#endif

  PR_Close(local_file_fd);

  /* read until EOF */
  readBuffer = PORT_Alloc(READ_BUFFER_SIZE);
  if (! readBuffer)
    exitErr("Out of memory", GENERAL_ERROR);

  local_file_fd = PR_Open(outfileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
			  PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IWGRP | PR_IROTH);
  if (local_file_fd == NULL)
    {
      fprintf (stderr, "could not open output file %s\n", outfileName);
      return SECFailure;
    }
  while (PR_TRUE)
    {
      numBytes = PR_Read(sslSocket, readBuffer, READ_BUFFER_SIZE);
      if (numBytes == 0)
	break;	/* EOF */

      if (numBytes < 0)
	{
	  secStatus = SECFailure;
	  break;
	}
#if DEBUG
      countRead += numBytes;
#endif
      /* Write to output file */
      numBytes = PR_Write(local_file_fd, readBuffer, numBytes);
      if (numBytes < 0)
	{
	  fprintf (stderr, "could not write to %s\n", outfileName);
	  secStatus = SECFailure;
	  break;
	}
#if DEBUG
      fprintf(stderr, "***** Connection read %d bytes (%d total).\n", 
	      numBytes, countRead );
      readBuffer[numBytes] = '\0';
      fprintf(stderr, "************\n%s\n************\n", readBuffer);
#endif
    }

  PR_Free(readBuffer);
  PR_Close(local_file_fd);

  /* Caller closes the socket. */
#if DEBUG
  fprintf(stderr, "***** Connection read %d bytes total.\n", countRead);
#endif

  return secStatus;
}