DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_SIGNON

Source


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