DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_SIGNON

Source


1 package body FND_SIGNON as
2 /* $Header: AFSCSGNB.pls 120.12.12020000.2 2012/08/13 18:22:01 ctilley ship $ */
3 
4 
5 --
6 -- GENERIC_ERROR (Internal)
7 --
8 -- Set error message and raise exception for unexpected sql errors.
9 --
10 procedure GENERIC_ERROR(routine in varchar2,
11                         errcode in number,
12                         errmsg in varchar2) is
13 begin
14     fnd_message.set_name('FND', 'SQL_PLSQL_ERROR');
15     fnd_message.set_token('ROUTINE', routine);
16     fnd_message.set_token('ERRNO', errcode);
17     fnd_message.set_token('REASON', errmsg);
18     app_exception.raise_exception;
19 end;
20 
21 --
22 -- AUDIT_FORM_END (Internal) - Signon audit mark form endtimes
23 --
24 -- Stamp end_time of current record in soa forms table.
25 -- BUG:6076369, modified signature to include date argument so that
26 -- FNDDLTMP.sql/ICXDLTMP.sql can pass in LAST_CONNECT value to AUDIT_USER_END.
27 --
28 procedure AUDIT_FORM_END(login_id in number, pend_time in date default SYSDATE) is
29 pragma AUTONOMOUS_TRANSACTION;
30 begin
31     if login_id is null then
32 	return;
33     end if;
34 
35     -- Stamp end time on any current form for this login in FLRF
36     UPDATE FND_LOGIN_RESP_FORMS FLRF
37     SET END_TIME = pend_time
38     WHERE FLRF.LOGIN_ID = audit_form_end.login_id
39     AND FLRF.END_TIME is NULL;
40 
41     COMMIT;
42 exception
43 when no_data_found then
44     null;
45 end AUDIT_FORM_END;
46 
47 --
48 -- AUDIT_RESPONSIBILITY_END (Internal) - Signon audit mark resp endtimes
49 --
50 -- Stamp end_time of current record in soa resps table.
51 --
52 -- Bug:6076369, modified signature to include a date argument so that
53 -- ICXDLTMP.sql/FNDDLTNP.sql can pass in LAST_CONNECT value to AUDIT_USER_END.
54 --
55 procedure AUDIT_RESPONSIBILITY_END(login_id in number,pend_time in date default
56 SYSDATE) is
57 pragma AUTONOMOUS_TRANSACTION;
58 begin
59     if login_id is null then
60 	return;
61     end if;
62 
63     -- Stamp end time on any current resp for this login in FLR
64     UPDATE FND_LOGIN_RESPONSIBILITIES FLR
65     SET END_TIME = pend_time
66     WHERE FLR.LOGIN_ID = audit_responsibility_end.login_id
67     AND FLR.END_TIME is NULL;
68 
69     -- End any open forms
70     AUDIT_FORM_END(login_id,pend_time);
71     COMMIT;
72 exception
73 when no_data_found then
74     null;
75 end AUDIT_RESPONSIBILITY_END;
76 
77 --
78 -- AUDIT_USER_END (Internal) - Signon audit mark user endtimes
79 --
80 -- Set end_time or current record in soa logins table.
81 --
82 -- BUG:6076369, modified signature to include date argument so that
83 -- FNDDLTMP.sql/ICXDLTMP.sql can pass in LAST_CONNECT value to AUDIT_USER_END.
84 --
85 procedure AUDIT_USER_END(login_id in number, pend_time in date default SYSDATE) is
86 pragma AUTONOMOUS_TRANSACTION;
87 l_spid varchar2(30);
88 begin
89 
90     if login_id is null then
91 	return;
92     else
93       -- Get the processes for this login_id as the same SPID will be associated
94       -- with different login_ids
95       select spid into l_spid from fnd_logins
96       where login_id = audit_user_end.login_id;
97     end if;
98 
99     -- Stamp end time on current login in FL
100 
101     UPDATE FND_LOGINS FL
102     SET END_TIME = pend_time
103     WHERE FL.LOGIN_ID = audit_user_end.login_id;
104 
105     -- Bug 11904176: end date the associated SPIDs
106     if (l_spid is not null) then
107       UPDATE FND_LOGINS FL
108       SET END_TIME = pend_time
109       where spid = l_spid;
110     end if;
111 
112 
113     -- End any open resps
114     AUDIT_RESPONSIBILITY_END(login_id, pend_time);
115     COMMIT;
116 
117 exception
118 when no_data_found then
119     null;
120 end AUDIT_USER_END;
121 
122 --
123 -- AUDIT_FORM - Signon audit form begin | end
124 --
125 -- If END_FORM
126 --   Stamp end time on current form record.
127 -- If BEGIN_FORM
128 --   Insert new soa record for form level auditing.
129 --
130 procedure AUDIT_FORM(login_id in number,
131                      login_resp_id in number,
132                      form_application in varchar2,
133                      form_name in varchar2,
134                      audit_level in varchar2 DEFAULT 'D',
135                      begin_flag in number DEFAULT 0) is
136 pragma AUTONOMOUS_TRANSACTION;
137 begin
138     if (begin_flag = 0) then
139         --
140         -- END_FORM call
141         -- Stamp end time on current form record.
142 	--
143         begin
144         -- JWSMITH bug 1879642 - added FLRF.END_TIME is null
145             UPDATE FND_LOGIN_RESP_FORMS FLRF
146             SET END_TIME = SYSDATE
147             WHERE FLRF.LOGIN_ID = audit_form.login_id
148             AND FLRF.LOGIN_RESP_ID = audit_form.login_resp_id
149             AND FLRF.END_TIME IS NULL
150 	    AND (FLRF.FORM_ID, FLRF.FORM_APPL_ID) =
151 		(SELECT F.FORM_ID, F.APPLICATION_ID
152 		 FROM FND_FORM F, FND_APPLICATION A
153                  WHERE F.FORM_NAME = audit_form.form_name
154 		 AND F.APPLICATION_ID = A.APPLICATION_ID
155 	         AND A.APPLICATION_SHORT_NAME = audit_form.form_application);
156         exception
157         when no_data_found then
158             null;
159         end;
160     else
161         --
162         -- BEGIN_FORM call
163         -- If form level auditing insert new form record.
164 	--
165         if (audit_level = 'D') then
166             INSERT INTO FND_LOGIN_RESP_FORMS
167             (LOGIN_ID, LOGIN_RESP_ID, FORM_APPL_ID, FORM_ID, START_TIME,
168              AUDSID)
169                 SELECT audit_form.login_id, audit_form.login_resp_id,
170                        A.APPLICATION_ID, F.FORM_ID, SYSDATE,
171                        userenv('SESSIONID')
172                 FROM FND_FORM F, FND_APPLICATION A
173                 WHERE F.FORM_NAME = audit_form.form_name
174                 AND F.APPLICATION_ID = A.APPLICATION_ID
175                 AND A.APPLICATION_SHORT_NAME = audit_form.form_application;
176         end if;
177     end if;
178     COMMIT;
179 exception
180 when others then
181     rollback;
182     generic_error('FND_SIGNON.AUDIT_FORM', SQLCODE, SQLERRM);
183 end AUDIT_FORM;
184 
185 --
186 -- AUDIT_RESPONSIBILITY - Signon audit responsibility
187 --
188 -- Insert new soa record for responsibility,
189 -- update pid in soa logins table.
190 --
191 procedure AUDIT_RESPONSIBILITY(audit_level	in varchar2,
192                                login_id		in number,
193                                login_resp_id	in out nocopy number,
194                                resp_appl_id	in number,
195                                resp_id			in number,
196                                terminal_id	in varchar2,
197                                spid				in varchar2) is
198 pragma AUTONOMOUS_TRANSACTION;
199     l_pid number;
200     l_serial number;
201     l_spid varchar2(30);
202 begin
203     -- Endstamp any previous resp record in this login.
204     -- This must be done regardless of level in case level was changed
205     -- during login.
206     AUDIT_RESPONSIBILITY_END(login_id);
207 
208     --
209     -- Change pid in logins table to reflect pid of current process.
210     -- This must be done when resp changes because a reconnect may
211     -- have caused pid to change.
212     --
213     SELECT P.PID, P.SERIAL#, P.SPID
214                INTO l_pid, l_serial, l_spid
215 	       FROM V$PROCESS P, V$SESSION S
216 	       WHERE S.AUDSID = USERENV('SESSIONID')
217                AND S.PADDR = P.ADDR;
218 
219     UPDATE FND_LOGINS FL
220     SET PID = l_pid,
221         SERIAL# = l_serial,
222         PROCESS_SPID = l_spid
223     WHERE FL.LOGIN_ID = audit_responsibility.login_id;
224 
225     -- If resp/form level auditing insert record for new resp
226     if (audit_level in ('C', 'D')) then
227         --
228         -- Bug 3457883: The unique index FND_LOGIN_RESPONSIBILITIES_U1 is being violated when a
229         -- responsibility is relaunched within an existing ICX session.  This was brought about
230         -- by the changes in bug 3043856 wherein the login_id obtained by ICX is not used throughout
231         -- the session.  A new sequence, FND_LOGIN_RESPONSIBILITIES_S, is created to generate unique
232         -- values for login_resp_id and will be used when inserting records into
233         -- FND_LOGIN_RESPONSIBILITIES.  The login_resp_id generated will be passed back to the API
234         -- calling fnd_signon.audit_responsibility().
235         --
236 		  -- If login_resp_id is null, then generate one.
237 		  if (login_resp_id is null) then
238 		      select FND_LOGIN_RESPONSIBILITIES_S.nextval into login_resp_id from dual;
239 		  end if;
240 
241         INSERT INTO FND_LOGIN_RESPONSIBILITIES
242         (LOGIN_ID, LOGIN_RESP_ID, RESP_APPL_ID, RESPONSIBILITY_ID, START_TIME,
243          AUDSID)
244         VALUES (audit_responsibility.login_id,
245                 audit_responsibility.login_resp_id,
246                 audit_responsibility.resp_appl_id,
247                 audit_responsibility.resp_id, SYSDATE,
248                 userenv('SESSIONID'));
249 
250 	-- If auditing at form level add a new record for the signon
251 	-- form under the new responsibility.
252 	if (audit_level = 'D') then
253             AUDIT_FORM(login_id, login_resp_id, 'FND', 'FNDSCSGN',
254 		       audit_level, 1);
255 	end if;
256     end if;
257     COMMIT;
258 exception
259 when others then
260     rollback;
261     generic_error('FND_SIGNON.AUDIT_RESPONSIBILITY', SQLCODE, SQLERRM);
262 end AUDIT_RESPONSIBILITY;
263 
264 --
265 -- AUDIT_USER - Begin user level signon auditing
266 --
267 -- Insert new soa record for login,
268 -- create new login_id for this signon.
269 --
270 procedure AUDIT_USER(login_id in out nocopy number,
271                      audit_level in varchar2,
272                      user_id in number,
273                      terminal_id in varchar2,
274                      login_name in varchar2,
275                      spid in varchar2,
276                      session_number in number) is
277 pragma AUTONOMOUS_TRANSACTION;
278     local_pid  number;
279     local_spid varchar2(30);
280     local_serial# number;
281     local_process_spid VARCHAR2(30);
282 begin
283     -- Endstamp any previous login or resp record.
284     -- This must be done regardless of level in case level was changed
285     -- during login.
286     AUDIT_USER_END(login_id);
287     AUDIT_RESPONSIBILITY_END(login_id);
288 
289     -- Create a new login id
290     SELECT FND_LOGINS_S.NEXTVAL INTO audit_user.login_id FROM SYS.DUAL;
291 
292     -- If auditing turned on insert record in FL for new login
293     -- bug 7160418, skip auditing for guest user
294     if (audit_level <> 'A') AND (user_id <> '6') then
295 	-- Get current oracle and system process ids
296 	begin
297 	    SELECT P.PID, S.PROCESS, P.SERIAL#, P.SPID
298 	    INTO local_pid, local_spid, local_serial#, local_process_spid
299 	    FROM V$PROCESS P, V$SESSION S
300 	    WHERE S.AUDSID = USERENV('SESSIONID')
301 	    AND S.PADDR = P.ADDR;
302 	exception
303 	when no_data_found then
304 	    local_pid := null;
305 	    local_spid := null;
306 	end;
307 
308 	-- Insert record
309         INSERT INTO FND_LOGINS
310         (LOGIN_ID, USER_ID, START_TIME, TERMINAL_ID,
311             LOGIN_NAME, PID, SPID, SESSION_NUMBER, SERIAL#,
312             PROCESS_SPID, LOGIN_TYPE)
313         VALUES(audit_user.login_id, audit_user.user_id, SYSDATE,
314                audit_user.terminal_id, audit_user.login_name,
315                local_pid, local_spid, audit_user.session_number,
316                local_serial#, local_process_spid, 'FORM');
317     end if;
318     COMMIT;
319 exception
320 when others then
321     rollback;
322     generic_error('FND_SIGNON.AUDIT_USER', SQLCODE, SQLERRM);
323 end AUDIT_USER;
324 
325 --
326 -- AUDIT_END - End signon audit
327 --
328 -- End stamp last user and resp record when exiting.
329 --
330 procedure AUDIT_END(login_id in number) is
331 pragma AUTONOMOUS_TRANSACTION;
332 begin
333     -- Endstamp any previous signon audit records
334     AUDIT_USER_END(login_id);
335     COMMIT;
336 exception
337 when others then
338     rollback;
339     generic_error('FND_SIGNON.AUDIT_END', SQLCODE, SQLERRM);
340 end AUDIT_END;
341 
342 --
343 -- NEW_SESSION - Misc signon things
344 --
345 -- Get new session number, check password expiration, etc
346 --
347 procedure NEW_SESSION(UID in  number,
348                       SID out nocopy number,
349                       EXPIRED out nocopy varchar2) is
350     LSID number;
351 begin
352     --
353     -- Fetch and lock session number
354     --
355     -- Bug 7160418 skip guest user as we do not audit guest
356     if (UID <> 6) then
357        select SESSION_NUMBER
358        into   LSID
359        from   FND_USER
360        where  USER_ID = UID
361        for    update of SESSION_NUMBER, LAST_LOGON_DATE;
362        LSID := LSID + 1;
363        SID  := LSID;
364        --
365        -- Update session number, set logon date
366        --
367        update FND_USER
368        set    LAST_LOGON_DATE = SYSDATE,
369            SESSION_NUMBER = LSID
370        where  USER_ID = UID;
371 
372       --
373       -- Test for Expired password
374       --
375       begin
376         select 'Y'
377         into   EXPIRED
378         from   FND_USER
379         where  USER_ID = UID
380         and    ENCRYPTED_USER_PASSWORD <> 'EXTERNAL'  -- Bug #2288977 --
381         and    (PASSWORD_DATE is NULL or
382                 (PASSWORD_LIFESPAN_ACCESSES is not NULL and
383                      nvl(PASSWORD_ACCESSES_LEFT, 0) < 1) or
384                 (PASSWORD_LIFESPAN_DAYS is not NULL and
385                  SYSDATE >= PASSWORD_DATE + PASSWORD_LIFESPAN_DAYS));
386       exception
387         when no_data_found then
388             EXPIRED := 'N';
389       end;
390       --
391       -- Decrement password accesses left
392       --
393       begin
394         update FND_USER
395         set    PASSWORD_ACCESSES_LEFT = PASSWORD_ACCESSES_LEFT - 1
396         where  USER_ID = UID
397         and    PASSWORD_ACCESSES_LEFT > 0;
398       exception
399         when no_data_found then
400             null;
401       end;
402     else
403        -- Bug 7160418 skip guest user as we do not audit guest
404        -- We will fall into this else for GUEST user uid=6.
405        SID := -1;
406        EXPIRED := 'N';
407     end if;
408 
409     commit;
410 exception
411 when others then
412     generic_error('FND_SIGNON.NEW_SESSION', SQLCODE, SQLERRM);
413 end NEW_SESSION;
414 
415 --
416 -- Bug 3375261. new_icx_session(user_id,login_id,expired)
417 -- is called by Java APIs
418 -- SessionManager.validateLogin and WebAppsContext.createSession,
419 -- this causes the functions in new_icx_session to be executed
420 -- twice in a local login flow. The fix is to split the functionality
421 -- of new_icx_session into two new APIs:
422 -- (1) is_pwd_expired: performs password expiration related operations,
423 --     to be used when authenticating a user/pwd pair
424 -- (2) new_icx_session(UID,l_login_id): performs auditing and
425 --     session number related operation, to be used when a session
426 --     is created.
427 /* tests whether a password has expired or not, updates
428  * expiration related bookkeeping data in fnd_user table if necessary.
429  * update last_logon_date in fnd_user
430  */
431 procedure is_pwd_expired(UID in  number,
432                          EXPIRED out nocopy varchar2) is
433 pragma AUTONOMOUS_TRANSACTION;
434 begin
435     --
436     -- Test for Expired password
437     --
438     begin
439         select 'Y'
440         into   EXPIRED
441         from   FND_USER
442         where  USER_ID = UID
443         and    ENCRYPTED_USER_PASSWORD <> 'EXTERNAL'  -- Bug #2288977 --
444         and    (PASSWORD_DATE is NULL or
445                 (PASSWORD_LIFESPAN_ACCESSES is not NULL and
446                      nvl(PASSWORD_ACCESSES_LEFT, 0) < 1) or
447                 (PASSWORD_LIFESPAN_DAYS is not NULL and
448                  SYSDATE >= PASSWORD_DATE + PASSWORD_LIFESPAN_DAYS));
449     exception
450         when no_data_found then
451             EXPIRED := 'N';
452     end;
453     --
454     -- Decrement password accesses left
455     --
456     begin
457         update FND_USER
458         set    PASSWORD_ACCESSES_LEFT = PASSWORD_ACCESSES_LEFT - 1
459         where  USER_ID = UID
460         and    PASSWORD_ACCESSES_LEFT > 0;
461     exception
462         when no_data_found then
463             null;
464     end;
465 
466     update FND_USER
467     set    LAST_LOGON_DATE = SYSDATE
468     where  USER_ID = UID;
469 
470     commit;
471 exception
472 when others then
473     rollback;
474     generic_error('FND_SIGNON.is_pwd_expired', SQLCODE, SQLERRM);
475 end is_pwd_expired;
476 
477 /*
478  * updates session_number in fnd_user table.
479  * generate auditing record
480  */
481 procedure new_icx_session(UID   IN NUMBER,
482                           login_id  OUT nocopy NUMBER) IS
483 begin
484    new_proxy_icx_session(UID, null, login_id);
485 end new_icx_session;
486 
487 /*
488  * updates session_number in fnd_user table.
489  * generate auditing record
490  * Same as new_icx_session except a single change for handling SIGNONAUDIT:LEVEL
491  * differently for Proxy Sessions.
492  */
493 procedure new_proxy_icx_session(UID   IN NUMBER,
494                           proxy_user IN NUMBER,
495                           login_id  OUT nocopy NUMBER) IS
496 LSID			NUMBER;
497 l_login_id              NUMBER;
498 l_audit_level           VARCHAR2(1);
499 l_session_id            NUMBER;
500 l_proxy_user_id         NUMBER;
501 begin
502     --
503     -- Fetch and lock session number
504     --
505     -- Bug 7160418 skip guest user as we do not audit guest
506     if (UID <> 6) then
507        select SESSION_NUMBER
508        into   LSID
509        from   FND_USER
510        where  USER_ID = UID
511        for    update of SESSION_NUMBER, LAST_LOGON_DATE;
512        LSID := LSID + 1;
513        --
514        -- Update session number, set logon date
515        --
516        update FND_USER
517        set    LAST_LOGON_DATE = SYSDATE,
518            SESSION_NUMBER = LSID
519        where  USER_ID = UID;
520     else
521        -- Bug 7160418 , fall into this else for GUEST user, uid=6
522        LSID := -1;
523     end if;
524 
525      SELECT  userenv('SESSIONID')
526      INTO    l_session_id
527      FROM    dual;
528 
529     /*
530      * Special handling of 'SIGNONAUDIT:LEVEL' for proxy sessions
531      */
532     /* Proxy info is already passed to this api
533      * so no need to call Fnd_Session_Management.isProxySession
534      */
535      l_proxy_user_id := proxy_user;
536 
537      if ((l_proxy_user_id is not NULL) AND
538          (l_proxy_user_id <> -1)) then
539        l_audit_level := 'D';
540      else
541        if (FND_GLOBAL.USER_ID = -1) or (FND_GLOBAL.USER_ID = 6) then
542          l_audit_level:=
543 	     fnd_profile.value_specific('SIGNONAUDIT:LEVEL', UID);
544        else
545          l_audit_level:= fnd_profile.value('SIGNONAUDIT:LEVEL');
546        end if;
547      end if;
548 
549 
550      audit_user(l_login_id, l_audit_level, UID,
551                 NULL, NULL, NULL, LSID);
552 
553     -- Bug 7160418 skip guest user as we do not audit guest
554     if (UID <> 6) then
555      INSERT INTO
556         fnd_appl_sessions(login_type, login_id, audsid, start_time)
557      VALUES ('AOLJ', l_login_id, l_session_id, Sysdate);
558     end if;
559 
560      login_id := l_login_id;
561 exception
562 when others then
563     login_id := 0;
564     generic_error('FND_SIGNON.NEW_PROXY_ICX_SESSION', SQLCODE, SQLERRM);
565 end new_proxy_icx_session;
566 
567 --
568 -- Update_Desktop_Object (PRIVATE)
569 --   Update a function value on the desktop.
570 --
571 procedure Update_Desktop_Object(
572   func_name in varchar2,
573   func_sequence in number,
574   user_id in number,
575   resp_id in number,
576   appl_id in number,
577   login_id in number)
578 is
579 begin
580   if (func_name is null) then
581     -- Delete if value nulled out
582     delete from FND_USER_DESKTOP_OBJECTS
583     where USER_ID = update_desktop_object.user_id
584     and APPLICATION_ID = update_desktop_object.appl_id
585     and RESPONSIBILITY_ID = update_desktop_object.resp_id
586     and TYPE = 'FUNCTION'
587     and SEQUENCE = update_desktop_object.func_sequence;
588   else
589     -- Try for update
590     update FND_USER_DESKTOP_OBJECTS set
591       FUNCTION_NAME = update_desktop_object.func_name,
592       LAST_UPDATE_DATE = sysdate,
593       LAST_UPDATED_BY = update_desktop_object.user_id,
594       LAST_UPDATE_LOGIN = update_desktop_object.login_id
595     where USER_ID = update_desktop_object.user_id
596     and APPLICATION_ID = update_desktop_object.appl_id
597     and RESPONSIBILITY_ID = update_desktop_object.resp_id
598     and TYPE = 'FUNCTION'
599     and SEQUENCE = update_desktop_object.func_sequence;
600 
601     if (sql%rowcount = 0) then
602       -- Insert new row if not found
603       insert into FND_USER_DESKTOP_OBJECTS (
604         DESKTOP_OBJECT_ID,
605         USER_ID,
606         APPLICATION_ID,
607         RESPONSIBILITY_ID,
608         OBJECT_NAME,
609         FUNCTION_NAME,
610         OBJECT_LABEL,
611         PARAMETER_STRING,
612         SEQUENCE,
613         LAST_UPDATE_DATE,
614         LAST_UPDATED_BY,
615         CREATION_DATE,
616         CREATED_BY,
617         LAST_UPDATE_LOGIN,
618         TYPE)
619       select
620         FND_DESKTOP_OBJECT_ID_S.NEXTVAL,
621         update_desktop_object.user_id,
622         update_desktop_object.appl_id,
623         update_desktop_object.resp_id,
624         'FUNCTION',
625         update_desktop_object.func_name,
626         'FUNCTION',
627         '',
628         update_desktop_object.func_sequence,
629         sysdate,
630         update_desktop_object.user_id,
631         sysdate,
632         update_desktop_object.user_id,
633 	update_desktop_object.login_id,
634         'FUNCTION'
635       from sys.dual;
636     end if;
637   end if;
638 exception
639   when others then
640     generic_error('FND_SIGNON.UPDATE_DESKTOP_OBJECT', SQLCODE, SQLERRM);
641 end;
642 
643 --
644 -- UPDATE_NAVIGATOR
645 --
646 -- Update navigator info for current user/resp.
647 --
648 procedure UPDATE_NAVIGATOR(
649     USER_ID in number,
650     RESP_ID in number,
651     APPL_ID in number,
652     LOGIN_ID in number,
653     FUNCTION1 in varchar2,
654     FUNCTION2 in varchar2,
655     FUNCTION3 in varchar2,
656     FUNCTION4 in varchar2,
657     FUNCTION5 in varchar2,
658     FUNCTION6 in varchar2,
659     FUNCTION7 in varchar2,
660     FUNCTION8 in varchar2,
661     FUNCTION9 in varchar2,
662     FUNCTION10 in varchar2,
663     WINDOW_WIDTH in number,
664     WINDOW_HEIGHT in number,
665     WINDOW_XPOS in number,
666     WINDOW_YPOS in number,
667     NEW_WINDOW_FLAG in varchar2) is
668 
669 begin
670   -- Save Hotlist functions to desktop objects
671   Fnd_Signon.Update_Desktop_Object(function1, 1,
672       user_id, resp_id, appl_id, login_id);
673   Fnd_Signon.Update_Desktop_Object(function2, 2,
674       user_id, resp_id, appl_id, login_id);
675   Fnd_Signon.Update_Desktop_Object(function3, 3,
676       user_id, resp_id, appl_id, login_id);
677   Fnd_Signon.Update_Desktop_Object(function4, 4,
678       user_id, resp_id, appl_id, login_id);
679   Fnd_Signon.Update_Desktop_Object(function5, 5,
680       user_id, resp_id, appl_id, login_id);
681   Fnd_Signon.Update_Desktop_Object(function6, 6,
682       user_id, resp_id, appl_id, login_id);
683   Fnd_Signon.Update_Desktop_Object(function7, 7,
684       user_id, resp_id, appl_id, login_id);
685   Fnd_Signon.Update_Desktop_Object(function8, 8,
686       user_id, resp_id, appl_id, login_id);
687   Fnd_Signon.Update_Desktop_Object(function9, 9,
688       user_id, resp_id, appl_id, login_id);
689   Fnd_Signon.Update_Desktop_Object(function10, 10,
690       user_id, resp_id, appl_id, login_id);
691 
692   -- Save window position to preferences
693   Fnd_Preference.Put(Fnd_Global.User_Name, 'FNDSCSGN',
694                      'WINDOW_WIDTH',
695                      fnd_number.number_to_canonical(window_width));
696   Fnd_Preference.Put(Fnd_Global.User_Name, 'FNDSCSGN',
697 	             'WINDOW_HEIGHT',
698                      fnd_number.number_to_canonical(window_height));
699   Fnd_Preference.Put(Fnd_Global.User_Name, 'FNDSCSGN',
700 		     'WINDOW_XPOS',
701 		     fnd_number.number_to_canonical(window_xpos));
702   Fnd_Preference.Put(Fnd_Global.User_Name, 'FNDSCSGN',
703 		     'WINDOW_YPOS',
704 		     fnd_number.number_to_canonical(window_ypos));
705   Fnd_Preference.Put(Fnd_Global.User_Name, 'FNDSCSGN',
706 		     'NEW_WINDOW_FLAG', new_window_flag);
707   commit;
708 exception
709 when others then
710     generic_error('FND_SIGNON.UPDATE_NAVIGATOR', SQLCODE, SQLERRM);
711 end UPDATE_NAVIGATOR;
712 
713 --
714 -- GET_NAVIGATOR_PREFERENCES
715 --   Get Navigator window sizing preferences.
716 --
717 procedure GET_NAVIGATOR_PREFERENCES(
718     WINDOW_WIDTH out nocopy number,
719     WINDOW_HEIGHT out nocopy number,
720     WINDOW_XPOS out nocopy number,
721     WINDOW_YPOS out nocopy number,
722     NEW_WINDOW_FLAG out nocopy varchar2)
723 is
724 begin
725   window_width := fnd_number.canonical_to_number(
726 		      Fnd_Preference.Get(Fnd_Global.User_Name,
727                       'FNDSCSGN', 'WINDOW_WIDTH'));
728   window_height := fnd_number.canonical_to_number(
729                       Fnd_Preference.Get(Fnd_Global.User_Name,
730                       'FNDSCSGN', 'WINDOW_HEIGHT'));
731   window_xpos := fnd_number.canonical_to_number(
732 		      Fnd_Preference.Get(Fnd_Global.User_Name,
733                       'FNDSCSGN', 'WINDOW_XPOS'));
734   window_ypos := fnd_number.canonical_to_number(
735                       Fnd_Preference.Get(Fnd_Global.User_Name,
736                       'FNDSCSGN', 'WINDOW_YPOS'));
737   new_window_flag := substrb(Fnd_Preference.Get(
738                        Fnd_Global.User_Name,
739                        'FNDSCSGN', 'NEW_WINDOW_FLAG'), 1, 1);
740 exception
741   when others then
742     generic_error('FND_SIGNON.GET_NAVIGATOR_PREFERENCES', SQLCODE, SQLERRM);
743 end GET_NAVIGATOR_PREFERENCES;
744 
745 --
746 -- SET_SESSION
747 --   Store session date whenever new session is created.
748 -- To be called in pre-form of any form opened in a new session.
749 -- This is to maintain session dates for AOL forms running under
750 -- HR responsibilities.
751 --
752 procedure SET_SESSION(session_date in varchar2) is
753     l_ses_date date;
754     hmask varchar2(11) := 'DD-MON-YYYY';
755 begin
756     l_ses_date := nvl(to_date(session_date, hmask),
757 		      trunc(sysdate));
758     insert into FND_SESSIONS (
759       SESSION_ID,
760       EFFECTIVE_DATE)
761     select
762       userenv('SESSIONID'),
763       l_ses_date
764     from sys.dual
765     where not exists
766       (select null
767       from FND_SESSIONS
768       where SESSION_ID = userenv('SESSIONID'));
769 
770     commit;
771 exception
772 when others then
773     generic_error('FND_SIGNON.SET_SESSION', SQLCODE, SQLERRM);
774 end SET_SESSION;
775 
776 -- Misc signon things for an aol/j session.
777 -- For internal use only.
778 
779 
780 -- PRIVATE_NEW_SESSION - wrapper call to new_session() to isolate autonomous
781 -- transaction to just the new_session.  This is required for bug 1950030 and
782 -- comes from the original requirement for bug 1870328, where the call to
783 -- new_session() - which does a commit - caused the calling Java save points
784 -- to be lost and all transactions before this call to get committed.
785 --
786 -- 1870328 tried adding the AUTONOMOUS_TRANSACTION pragma to new_aolj_session()
787 -- and assumed that the commit in new_session() was sufficient for the pragma,
788 -- but the additional insert clause required a commit as well...  Rather than
789 -- dealing with the INSERT and EXCEPTION handling under the pragma and to keep
790 -- the commit structure as close to original coding i decided to just isolate
791 -- new_session().
792 --
793 -- For internal use only.
794 
795 procedure PRIVATE_NEW_SESSION(pUID in  number,
796                       pSID in out nocopy number,
797                       pEXPIRED in out nocopy varchar2) is
798 pragma AUTONOMOUS_TRANSACTION;
799 begin
800    new_session(pUID,pSID,pEXPIRED);
801 end PRIVATE_NEW_SESSION;
802 
803 
804 /*
805  * NEW_AOLJ_SESSION
806  *   Wrapper to new_icx_session as it was deemed redundant, i.e. it performed
807  *   the same functionality as new_icx_session without the auditing.  All sessions
808  *   created should be audited.
809  *
810  * IN
811  *   user_id - User's ID
812  * OUT
813  *   p_loginID - Login ID of audit record (if successful)
814  *   p_expired - Expiration flag to check whether user's password has expired.
815  * RAISES
816  *   Never raises exceptions, places a message on the
817  *   message stack if an error is encountered.
818  */
819 PROCEDURE new_aolj_session(user_id   IN NUMBER,
820 						   login_id OUT nocopy NUMBER,
821                            expired  OUT nocopy VARCHAR2)
822   IS
823 BEGIN
824 
825 	new_icx_session(user_id, login_id, expired);
826 
827 EXCEPTION
828 	WHEN OTHERS THEN
829 		login_id := 0;
830 		expired := 'N';
831 		generic_error('FND_SIGNON.NEW_AOLJ_SESSION', SQLCODE, SQLERRM);
832 end NEW_AOLJ_SESSION;
833 
834 
835 --AUDIT_WEB_RESPONSIBILITY created to audit visits to Responsibilities within ICX.
836 --Not as detailed as other resp audits.. but that is due to lack of reliable details within ICX.
837 procedure AUDIT_WEB_RESPONSIBILITY(login_id in number,
838                                    login_resp_id in number,
839                                    resp_appl_id in number,
840                                    resp_id in number)
841    IS
842 pragma AUTONOMOUS_TRANSACTION;
843     audit_level VARCHAR2(1);
844     rows_exist NUMBER := 0;
845     l_audit_level VARCHAR2(1);
846     l_proxy_user_id NUMBER;
847     l_session_id NUMBER;
848 
849 BEGIN
850 
851      select userenv('SESSIONID') into l_session_id from dual;
852      l_proxy_user_id := fnd_session_management.isProxySession(null);
853 
854 
855      if (l_proxy_user_id is not NULL) then
856        l_audit_level := 'D';
857      else
858        l_audit_level:=fnd_profile.value('SIGNONAUDIT:LEVEL');
859      end if;
860 
861     -- If resp/form level auditing insert record for new resp
862     if (l_audit_level in ('C', 'D')) then
863 
864        --see if there is already a row
865        SELECT count(*) INTO rows_exist
866           FROM fnd_login_responsibilities
867           WHERE login_id=audit_web_responsibility.login_id
868           AND login_resp_id=audit_web_responsibility.login_resp_id;
869 
870 
871        IF rows_exist=0 THEN
872 
873         INSERT INTO FND_LOGIN_RESPONSIBILITIES
874         (LOGIN_ID, LOGIN_RESP_ID, RESP_APPL_ID, RESPONSIBILITY_ID, START_TIME,
875          AUDSID)
876         VALUES (audit_web_responsibility.login_id,
877                 audit_web_responsibility.login_resp_id,
878                 audit_web_responsibility.resp_appl_id,
879                 audit_web_responsibility.resp_id, SYSDATE,
880                 userenv('SESSIONID'));
881 
882         END IF; -- rows_exist
883 
884     end if; -- audit_level in ..
885     COMMIT;
886 exception
887 when others then
888     rollback;
889 
890     generic_error('FND_SIGNON.AUDIT_WEB_RESPONSIBILITY', SQLCODE, SQLERRM);
891 end AUDIT_WEB_RESPONSIBILITY;
892 
893 /*
894  * NEW_ICX_SESSION
895  *   Creates a session and updates auditing tables for each session created.
896  *
897  * IN
898  *   user_id - User's ID
899  * OUT
900  *   p_loginID - Login ID of audit record (if successful)
901  *   p_expired - Expiration flag to check whether user's password has expired.
902  * RAISES
903  *   Never raises exceptions, places a message on the
904  *   message stack if an error is encountered.
905  */
906 
907 PROCEDURE new_icx_session(user_id   IN NUMBER,
908 						  login_id OUT nocopy NUMBER,
909 						  expired  OUT nocopy VARCHAR2)
910 	IS
911 		l_session_number	NUMBER;
912 		l_login_id			NUMBER;
913 		l_expired			VARCHAR2(1);
914 		l_audit_level		VARCHAR2(1);
915 		l_session_id		NUMBER;
916                 l_proxy_user_id         NUMBER;
917 BEGIN
918 
919 		PRIVATE_NEW_SESSION(user_id, l_session_number, l_expired);
920 		--
921 		-- Bug 3238722: The login_id generated by FND_LOGINS_S is not being recorded in
922 		-- FND_LOGINS when a user-level value for the profile option 'Sign-On Audit:Level' is set
923 		-- but a site-level value is not.  This happens when the audit level value returned by
924 		-- fnd_profile.value returns the site-level when the context is not set.  The code needs to
925 		-- check if the context is set by an FND_GLOBAL.USER_ID call.  If the return value is -1,
926 		-- then the context is not set.  If the context is not set, the code should call
927 		-- fnd_profile.value_specific and pass in the user_id to return an accurate value for
928 		-- the audit level.  Once an accurate value for the profile is returned, the login_id will
929 		-- be properly recorded in FND_LOGINS.
930 		--
931 
932 		SELECT	userenv('SESSIONID')
933 		INTO	l_session_id
934 		FROM	dual;
935 
936     begin
937       select session_id into l_session_id
938       from ICX_SESSIONS
939       where session_id= l_session_id;
940 
941 		  l_proxy_user_id :=
942 			  fnd_session_management.isProxySession(l_session_id);
943     exception
944       when no_data_found then
945        l_proxy_user_id := NULL;
946     end;
947 
948 		-- Proxy sessions are always audited at FORM level irrespective
949 		-- of SIGNONAUDIT:LEVEL profile option
950 		if (l_proxy_user_id is not NULL) then
951 		   l_audit_level := 'D';
952 		else
953 		   if (FND_GLOBAL.USER_ID = -1) OR (FND_GLOBAL.USER_ID = 6)  then
954                      l_audit_level:= fnd_profile.value_specific('SIGNONAUDIT:LEVEL', user_id);
955                    else
956                       l_audit_level:= fnd_profile.value('SIGNONAUDIT:LEVEL');
957 		   end if;
958 		end if;
959 
960 
961 		audit_user(l_login_id, l_audit_level, user_id, NULL, NULL, NULL, l_session_number);
962 
963               -- Bug 7160418 skip guest user as we do not audit guest
964               if (UID <> 6) then
965 		INSERT INTO fnd_appl_sessions(login_type, login_id, audsid, start_time)
966 		VALUES ('AOLJ', l_login_id, l_session_id, Sysdate);
967               end if;
968 
969 		login_id := l_login_id;
970 		expired := l_expired;
971 
972 EXCEPTION
973 		WHEN OTHERS THEN
974 			login_id := 0;
975 			expired := 'N';
976 			-- Changed FND_SIGNON.NEW_AOLJ_SESSION to FND_SIGNON.NEW_ICX_SESSION
977 			-- for consistency.
978 			generic_error('FND_SIGNON.NEW_ICX_SESSION', SQLCODE, SQLERRM);
979 end NEW_ICX_SESSION;
980 
981 /* BUG:5052314: API to retrieve number of unsuccessful logins */
982 /* previous to current login */
983 FUNCTION get_invalid_logins(p_userID number) return NUMBER
984  IS
985 
986    number_of_unsuccessful_logins NUMBER:= 0;
987    l_user_id NUMBER;
988 
989 
990 BEGIN
991 
992    -- check user id exist.
993    select  user_id
994    into    l_user_id
995    from    FND_USER
996    where   user_id = p_userID;
997 
998  -- Bug 7169414 - rewrite - changed query to be the same used in the Forms login
999 
1000    select  count(ul.USER_ID)
1001    into    number_of_unsuccessful_logins
1002    from    fnd_unsuccessful_logins ul,  fnd_user u
1003    where   u.user_id = l_user_id
1004    and     ul.user_id = u.user_id
1005    and     ul.attempt_time > nvl(u.last_logon_date, u.last_update_date);
1006 
1007    return number_of_unsuccessful_logins;
1008 
1009 EXCEPTION when NO_DATA_FOUND then
1010 
1011 -- raise no data found error.
1012 fnd_message.set_name('FND','SQL_PLSQL_ERROR');
1013 fnd_message.set_token('ROUTINE','FND_AOLJ_UTIL.get_invalid_logins()');
1014 fnd_message.set_token('ERRNO',1403 );
1015 fnd_message.set_token('REASON','Invalid User ID provided');
1016 app_exception.raise_exception;
1017 
1018 when OTHERS then
1019 
1020 --raise generic error.
1021 fnd_message.set_name('FND','SQL_PLSQL_ERROR');
1022 fnd_message.set_token('ROUTINE','FND_AOLJ_UTIL.get_invalid_logins()');
1023 fnd_message.set_token('ERRNO',SUBSTR(sqlerrm,5,5));
1024 fnd_message.set_token('REASON', sqlerrm);
1025 app_exception.raise_exception;
1026 
1027 
1028 END get_invalid_logins;
1029 
1030 end FND_SIGNON;