Cobol подключиться к оракулу не удалось, когда поле пароля определено дольше, чем реальное значение пароля

Моя программа COBOL не может подключиться к Oracle, если поле пароля определено дольше, чем фактическая длина пароля для пользователя. то есть, если значение пароля - «mypasswd», переменная хоста для хранения пароля должна быть определена с помощью «PIC X (8)», в противном случае соединение не будет установлено; Например:

 1         IDENTIFICATION DIVISION.
 2         PROGRAM-ID. SAMPLE.
 3         ENVIRONMENT DIVISION.
 4         DATA DIVISION.
 5         WORKING-STORAGE SECTION.
 6             EXEC SQL BEGIN DECLARE SECTION END-EXEC.
 7         01 USERNAME      PIC         X(010).
 8         01 PASSWD        PIC         X(010).
 9         01 DBSTRING      PIC         X(020).
10             EXEC SQL END DECLARE SECTION END-EXEC.
11             EXEC SQL INCLUDE SQLCA END-EXEC.
12
13         PROCEDURE DIVISION.
14         BEGIN-PGM.
15             EXEC SQL WHENEVER SQLERROR
16              DO PERFORM SQL-ERROR
17             END-EXEC.
18         LOGON.
19             MOVE "myuser" TO USERNAME.
20             MOVE "mypasswd" TO PASSWD.
21             MOVE "mydb" TO DBSTRING.
22             EXEC SQL
23              CONNECT :USERNAME IDENTIFIED BY :PASSWD USING :DBSTRING
24             END-EXEC.
25         LOGOUT.
26             DISPLAY "HAVE A GOOD DAY.".
27             EXEC SQL COMMIT WORK RELEASE END-EXEC.
28             STOP RUN.
29         SQL-ERROR.
30             EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
31             DISPLAY "ORACLE ERROR DETECTED:".
32             DISPLAY SQLERRMC.
33             EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
34             STOP RUN.

Я должен получить сбой подключения: ОБНАРУЖЕНА ОШИБКА ORACLE: ORA-01017: неверное имя пользователя / пароль; вход в систему запрещен

Но когда я меняю определение поля пароля на: 8 01 PASSWD PIC X (008). т.е. длина равна длине реального значения пароля (length ("mypasswd") = 8), программа может успешно подключиться к Oracle.

Моя ситуация такова, что нам нужно, чтобы пользователи могли предоставить свое собственное имя пользователя и пароль, поэтому мы должны сначала определить поля имени пользователя и пароля, достаточно длинные, чтобы сохранить максимальную длину, которую мы разрешаем. Однако, как указано выше, все запросы на соединение будут отклонены, если пользователь выберет пароль короче максимального.

Программа перенесена из старой версии Oracle 11.2.0.1.0, где у нас нет этой проблемы, программа работала нормально, операция подключения прошла успешно. Но проблема возникла после перехода на Oracle 12.1.0.1.0.


person HiHui    schedule 11.04.2014    source источник
comment
Вы использовали свою любимую поисковую систему? Спросил Oracle? Посмотрели в документации?   -  person Bill Woodger    schedule 11.04.2014


Ответы (2)


Если вы используете Pro * COBOL, то эта ссылка для вас: http://docs.oracle.com/cd/A57673_01/DOC/api/doc/PCO18/ch1.htm#toc024

Он показывает, как определить поля вашего имени пользователя и пароля как РАЗЛИЧНЫЕ.

 WORKING STORAGE SECTION. 

     ... 

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 

         01  USERNAME  PIC X(10) VARYING. 

         01  PASSWD    PIC X(10) VARYING. 

         ... 

     EXEC SQL END DECLARE SECTION END-EXEC. 

     ... 

 PROCEDURE DIVISION. 

 LOGON. 

     MOVE "SCOTT" TO USERNAME-ARR. 

     MOVE 5 TO USERNAME-LEN. 

     MOVE "TIGER" TO PASSWD-ARR. 

     MOVE 5 TO PASSWD-LEN. 

     EXEC SQL WHENEVER SQLERROR GOTO LOGON-ERROR END-EXEC. 

     EXEC SQL 

         CONNECT :USERNAME IDENTIFIED BY :PASSWD 

     END-EXEC. 

Как оказалось, приведенный пример не может быть полезен для вас напрямую (из комментариев), потому что ваши пароли не могут быть пятью длиной.

Это действительно не проблема. Вы можете рассчитать длину пароля для данного пользователя, а затем вместо буквального значения 5 использовать вычисленное вами значение.

@NealB показал в своем ответе простой способ сделать это (если у вас не может быть начальных или встроенных пробелов в пароле).

INSPECT PASSWD TALLYING PSSWDLEN FOR ALL SPACE
COMPUTE PSSWDLEN = LENGTH OF PASSWD - PSSWDLEN 

Если вы не можете использовать этот метод, выберите простую конструкцию цикла по вашему выбору, начиная с последнего байта поля пароля и продолжая, пока встречается пробел. Не упустите возможность полностью космического пространства.

В любом случае вы можете захотеть использовать тот же метод для имени пользователя, так как он будет более переносимым между различными вариантами Oracle / OS (в зависимости от того, что именно позволяет ему работать на вас). Я бы сделал это, если только это не станет абсолютно невозможным.

Вы упомянули о переходе на новую версию Oracle. Это поведение должно быть задокументировано в разделе «Сводка изменений» или аналогичном разделе документации. Если вы не можете найти ссылку на него, свяжитесь с Oracle и узнайте, что происходит.

Если вы не используете Pro * COBOL, вы можете имитировать эффект VARYING.

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 

         01  USERNAME.
             05  USERNAME-LEN BINARY PIC 9(4).
             05  USERNAME-VALUE      PIC X(10). 

         01  PASSWD.
             05  PASSWD-LEN BINARY PIC 9(4).
             05  PASSWD-VALUE      PIC X(10). 

     END-EXEC. 

Потом:

 LOGON. 

     MOVE "SCOTT" TO USERNAME-VALUE. 

     MOVE 5 TO USERNAME-LEN. 

     MOVE "TIGER" TO PASSWD-VALUE. 

     MOVE 5 TO PASSWD-LEN. 

     EXEC SQL WHENEVER SQLERROR GOTO LOGON-ERROR END-EXEC. 

     EXEC SQL 

         CONNECT :USERNAME IDENTIFIED BY :PASSWD 

     END-EXEC. 

Возможно, вам придется попробовать:

         01  USERNAME.
             05  USERNAME-LEN BINARY PIC 9(4).
             05  USERNAME-VALUE.
                 10  FILLER OCCURS 1 TO 10 TIMES
                     DEPENDING ON USERNAME-LEN.
                     15  FILLER      PIC X. 

         01  PASSWD.
             05  PASSWD-LEN BINARY PIC 9(4).
             05  PASSWD-VALUE.
                 10  FILLER OCCURS 1 TO 10 TIMES
                     DEPENDING ON PASSWD-LEN.
                     15  FILLER      PIC X. 

     END-EXEC. 

Если вы ничего не добьетесь с предложением, вам необходимо предоставить дополнительную информацию, например об ОС, версии COBOL, версии Oracle, а также о том, что вы пробовали и какие результаты вы получили от этих попыток.

person Bill Woodger    schedule 11.04.2014
comment
Спасибо, Билл. Я использую Pro * COBOL, ваше решение работает, как проверено, но в моем случае я не знаю точного значения пароля, поэтому MOVE 5 TO PASSD-LEN 'не работает, я не могу узнать длину пароля. - person HiHui; 14.04.2014
comment
Более того, эта проблема возникает только с полем «пароль», она не влияет на поле «имя пользователя», т. Е. Определение поля «имя пользователя» может быть длиннее, чем реальное значение имени пользователя. - person HiHui; 14.04.2014
comment
Обновил ответ для вас. - person Bill Woodger; 14.04.2014
comment
Спасибо, Билл. Я использую Pro * COBOL; и это решение сработало: 01 ИМЯ ПОЛЬЗОВАТЕЛЯ. 05 ИМЯ ПОЛЬЗОВАТЕЛЯ-LEN ДВОИЧНЫЙ РИС 9 (4). 05 ИМЯ ПОЛЬЗОВАТЕЛЯ-ЗНАЧЕНИЕ PIC X (10). но я не могу сделать предположение, что клиенты не будут использовать пробелы в своих паролях. И я подозреваю, что оракул внес некоторые изменения при обновлении с 11.2.0.1.0 до 12.1.0.1.0, я буду исследовать больше. - person HiHui; 14.04.2014
comment
Хорошо, так что зацикливайтесь сзади, чтобы подсчитать конечные пробелы, как я предложил в ответе. Используйте LENGTH OF / FUNCTION LENGTH, чтобы получить длину поля, начните с него и двигайтесь в обратном направлении, пока не найдете непустое поле. Сначала проверьте поле на наличие пустых полей, чтобы упростить завершение цикла. Сообщите нам, если вы найдете что-то от Oracle (поможет другим с той же проблемой). - person Bill Woodger; 14.04.2014
comment
Кстати, если возможно, я предпочитаю не вносить изменения в код. - person HiHui; 14.04.2014
comment
Да, не так ли все? В вашей документации для новой версии должно быть что-то связанное с этим, с объяснением, как вы должны с этим справляться. Это может потребовать изменения кода, а может и нет. Если упоминания о проблеме нет, обратитесь к Oracle. Затем они скажут вам, что нужно сделать. Это может потребовать изменения кода, а может и нет. В краткосрочной перспективе, чтобы все заработало, вам может потребоваться внести изменения, от которых позже можно будет отказаться. Зависит от того, что вы узнаете от Oracle. Возможно, кто-то, кто столкнулся с этим, увидит вопрос, но ударит Oracle. - person Bill Woodger; 14.04.2014

Вы пробовали использовать модификацию ссылки, чтобы настроить длину имени пользователя / пароля в запросе на соединение?

Я не из рода Oracle, но что-то вроде этого может сработать:

22             EXEC SQL
23              CONNECT :USERNAME(1:UNAMELEN) IDENTIFIED BY :PASSWD(1:PSSWDLEN) USING :DBSTRING
24             END-EXEC.

где UNAMELEN и PSSWDLEN - числовые переменные (например, PIC S9 (4) BINARY), содержащие фактическую длину имени пользователя и пароля.

Определить значения для UNAMELEN и PSSWDLEN можно с помощью команды INSPECT примерно так:

INSPECT PASSWD TALLYING PSSWDLEN FOR ALL SPACE
COMPUTE PSSWDLEN = LENGTH OF PASSWD - PSSWDLEN 

Это будет работать при условии, что пароли и имена пользователей не содержат внутренних пробелов. Если они это сделают, вам придется вычислять фактическую длину по-другому.

person NealB    schedule 11.04.2014
comment
Другая вещь, о которой я думал, это ограничивающий двоичный ноль, но поиск привел к кое-чему еще. Все это уже должно было быть предпринято, но поехали. - person Bill Woodger; 12.04.2014
comment
Привет, NealB, CONNECT: USERNAME (1: UNAMELEN) IDENTIFIED BY ... не работает с Pro COBOL, хотя USERNAME (1: UNAMELEN) является допустимым литералом COBOL, Pro COBOL не может его понять. - person HiHui; 14.04.2014
comment
ПРОВЕРЬТЕ ПАРОЛЬ, чтобы ограничить все пространство, разумно, но я не могу убедиться, есть ли у пользователя пробел в содержимом пароля. - person HiHui; 14.04.2014