]> granicus.if.org Git - sudo/commitdiff
new version from "Jeff A. Earickson" <jaearick@colby.edu>
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 4 Apr 1996 19:16:09 +0000 (19:16 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 4 Apr 1996 19:16:09 +0000 (19:16 +0000)
dce_pwent.c

index b6b204edd166ce0c798ecf1ad5bf7b6c9aa0f8ff..a10f0631f5228ca24247d11f4cbd2b24030e8ffa 100644 (file)
@@ -23,9 +23,9 @@
  *  (jaearick@colby.edu)
  *
  *  The code below basically comes from the examples supplied on
- *  the OSF DCE 1.0.3 manpages for the sec_login routines, with 
+ *  the OSF DCE 1.0.3 manpages for the sec_login routines, with
  *  enough additional polishing to make the routine work with the
- *  rest of sudo.  
+ *  rest of sudo.
  *
  *  This code is known to work on HP 700 and 800 series systems
  *  running HP-UX 9.X and 10.X, with either HP's version 1.2.1 of DCE.
 /*
  * Prototypes
  */
-static int check_dce_status    __P((error_status_t, char *));
+static int check_dce_status __P((error_status_t, char *));
 
 /*
  * Globals
  */
-static int             error_stat;
-static unsigned char   error_string[dce_c_error_string_len];
+static int      error_stat;
+static unsigned char    error_string[dce_c_error_string_len];
 
 
-/* returns 1 (true) if user is a valid DCE principal, 0 (false) otherwise */
+/* returns 1 ("true") if user is a valid DCE principal, 0 otherwise */
 int dce_pwent(username, plain_pw)
-    char *username;
-    char *plain_pw;
+char *username;
+char *plain_pw;
 {
-    struct passwd              *pwd;
-    sec_passwd_rec_t           password_rec;
-    sec_login_handle_t         login_context;
-    boolean32                  reset_passwd;
-    sec_login_auth_src_t       auth_src;
-    error_status_t             status;
-    unsigned32                 nbytes;
-
-    if(sec_login_setup_identity((unsigned_char_p_t) username,
-       sec_login_no_flags, &login_context, &status)) {
-
-       if (check_dce_status(status, "sec_login_setup_identity(1):"))
-           return(0);
-
-       password_rec.key.key_type = sec_passwd_plain;
-       password_rec.key.tagged_union.plain = (idl_char *) plain_pw;
-       password_rec.pepper = NULL;   
-       password_rec.version_number = sec_passwd_c_version_none;
-
-       if(sec_login_validate_identity(login_context, &password_rec,
-           &reset_passwd, &auth_src, &status)) {
-
-           if (check_dce_status(status, "sec_login_validate_identity(1):"))
-               return(0);
-
-           if (!sec_login_certify_identity(login_context, &status)) {
-               (void) fprintf(stderr, "Whoa! Bogus authentication server!\n");
-               (void) check_dce_status(status, "sec_login_certify_identity(1):"); 
-               return(0);
-           }
-
-           if(check_dce_status(status, "sec_login_certify_identity(2):"))
-               return(0);
-
-           (void) sec_login_set_context(login_context, &status);
-           if (check_dce_status(status, "sec_login_set_context:"))
-               return(0);
-
-           if (auth_src != sec_login_auth_src_network) {
-               (void) fprintf(stderr, "You have no network credentials\n");
-               return(0);
-           }
-           if (reset_passwd) {
-               (void) fprintf(stderr, "Your DCE password needs resetting\n");
-               return(0);
-           }
-
-           /* malloc() space for passwd structure */
-           nbytes = sizeof(struct passwd);
-           if ((pwd = (struct passwd *) malloc(nbytes)) == NULL) {
-               (void) fprintf(stderr, "malloc for passwd struct failed\n");
-               return(0);
-           }
-           (void) sec_login_get_pwent(login_context, (sec_login_passwd_t) pwd, &status);
-           (void) free(pwd);
-
-           if (check_dce_status(status, "sec_login_get_pwent:"))
-               return(0);
-
-           /*
-            * if we get to here, then the pwent above properly
-            * fetched the password structure from the DCE registry,
-            * so the user must be valid.  We don't really care what
-            * the user's registry password is, just that the user
-            * could be validated....
-            */
-           return(1);
-       } else {
-           if (check_dce_status(status, "sec_login_validate_identity(2):"))
-               return(0);
-           (void) sec_login_purge_context(&login_context, &status);
-           if (check_dce_status(status, "sec_login_purge_context:"))
-               return(0);
+       struct passwd           *pwd;
+       sec_passwd_rec_t        password_rec;
+       sec_login_handle_t      login_context;
+       boolean32                       reset_passwd;
+       sec_login_auth_src_t    auth_src;
+       error_status_t          status;
+       unsigned32                      nbytes;
+
+       /* create the local context of the DCE principal necessary   */
+       /* to perform authenticated network operations. The network  */
+       /* identity set up by this operation cannot be used until it */
+       /* is validated via sec_login_validate_identity(). */
+       if(sec_login_setup_identity((unsigned_char_p_t) username,
+               sec_login_no_flags,&login_context,&status))
+       {
+               if(check_dce_status(status,"sec_login_setup_identity(1):"))
+                       return(0);
+
+               password_rec.key.key_type = sec_passwd_plain;
+               password_rec.key.tagged_union.plain = (idl_char *) plain_pw;
+               password_rec.pepper = NULL;
+               password_rec.version_number = sec_passwd_c_version_none;
+
+               /* validate the login context with the password */
+               if(sec_login_validate_identity(login_context,&password_rec,
+                       &reset_passwd,&auth_src,&status))
+               {
+                       if(check_dce_status(status,"sec_login_validate_identity(1):"))
+                               return(0);
+
+                       /* Certify that the DCE Security Server used to set      */
+                       /* up and validate a login context is legitimate.  Makes */
+                       /* sure that we didn't get spoofed by another DCE server.*/
+                       if(!sec_login_certify_identity(login_context,&status))
+                       {
+                               fprintf(stderr,"Whoa! Bogus authentication server!\n");
+                               (void) check_dce_status(status,"sec_login_certify_identity(1):");
+                               return(0);
+                       }
+                       if(check_dce_status(status,"sec_login_certify_identity(2):"))
+                               return(0);
+
+                       /* sets the network credentials to those specified */
+                       /* by the now validated login context. */
+                       sec_login_set_context(login_context,&status);
+                       if(check_dce_status(status,"sec_login_set_context:"))
+                               return(0);
+
+                       /* oops, your credentials were no good. Possibly   */
+                       /* caused by clock times out of adjustment between */
+                       /* DCE client and DCE security server...           */
+                       if(auth_src != sec_login_auth_src_network)
+                       {
+                               fprintf(stderr,"You have no network credentials\n");
+                               return(0);
+                       }
+                       /* check if the password has aged and is no good */
+                       if(reset_passwd)
+                       {
+                               fprintf(stderr,"Your DCE password needs resetting\n");
+                               return(0);
+                       }
+
+                       /* malloc space for passwd structure */
+                       nbytes = sizeof(struct passwd);
+                       if((pwd = (struct passwd *) malloc(nbytes)) == NULL)
+                       {
+                               fprintf(stderr,"malloc for passwd struct failed\n");
+                               return(0);
+                       }
+                       /* we should be a valid user by this point.  Pull the */
+                       /* user's password structure from the DCE security    */
+                       /* server just to make sure.  If we get it with no    */
+                       /* problems, then we really are legitimate...         */
+                       sec_login_get_pwent(login_context,(sec_login_passwd_t) pwd,&status);
+                       free(pwd);
+                       if(check_dce_status(status,"sec_login_get_pwent:"))
+                               return(0);
+
+                       /************************************************************/
+                       /* if we get to here, then the pwent above properly fetched */
+                       /* the password structure from the DCE registry, so the user*/
+                       /*  must be valid.  We don't really care what the user's    */
+                       /* registry password is, just that the user could be        */
+                       /* validated.  In fact, if we tried to compare the local    */
+                       /* password to the DCE entry at this point, the operation   */
+                       /* would fail if the hidden password feature is turned on,  */
+                       /* because the password field would contain an asterisk.    */
+                       /*   Also go ahead and destroy the user's DCE login context */
+                       /* before we leave here (and don't bother checking the      */
+                       /* status), in order to clean up credentials files in       */
+                       /* /opt/dcelocal/var/security/creds.  By doing this, we are */
+                       /* assuming that the user will not need DCE authentication  */
+                       /* later in the program, only local authentication.  If this*/
+                       /* is not true, then the login_context will have to be      */
+                       /* returned to the calling program, and the context purged  */
+                       /* somewhere later in the program.                          */
+                       /************************************************************/
+                       sec_login_purge_context(&login_context,&status);
+                       return(1);
+               }
+               else
+               {
+                       if(check_dce_status(status,"sec_login_validate_identity(2):"))
+                               return(0);
+                       sec_login_purge_context(&login_context,&status);
+                       if(check_dce_status(status,"sec_login_purge_context:"))
+                               return(0);
+               }
        }
-    }
-    if (check_dce_status(status, "sec_login_setup_identity(2):"))
+       if(check_dce_status(status,"sec_login_setup_identity(2):")) return(0);
        return(0);
-
-    return(0);
 }
 
-/* returns 1 (true) for DCE "ok" status, 0 (false) otherwise */
-static int check_dce_status(input_status, comment) 
-    error_status_t input_status;
-    char *comment;
-{ 
-    if (input_status == rpc_s_ok)
-       return(0);
-
-    (void) dce_error_inq_text(input_status, error_string, &error_stat); 
-    (void) fprintf(stderr, "%s %s\n", comment, error_string); 
-
-    return(1);
+/* returns 0 for DCE "ok" status, 1 otherwise */
+static int check_dce_status(input_status, comment)
+error_status_t input_status;
+char *comment;
+{
+       if(input_status == rpc_s_ok) return(0);
+       dce_error_inq_text(input_status, error_string, &error_stat);
+       fprintf(stderr, "%s %s\n", comment, error_string);
+       return(1);
 }
-
-#endif /* HAVE_DCE */
+#endif /* HAVE_DCE */