/*
* Authorization routines for the CUPS scheduler.
*
- * Copyright 2007-2016 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
* Jelmer Vernooij.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more
+ * information.
*/
/*
static int compare_locations(cupsd_location_t *a,
cupsd_location_t *b);
static cupsd_authmask_t *copy_authmask(cupsd_authmask_t *am, void *data);
-#if !HAVE_LIBPAM
-static char *cups_crypt(const char *pw, const char *salt);
-#endif /* !HAVE_LIBPAM */
static void free_authmask(cupsd_authmask_t *am, void *data);
#if HAVE_LIBPAM
static int pam_func(int, const struct pam_message **,
* client...
*/
- pass = cups_crypt(password, pw->pw_passwd);
+ pass = crypt(password, pw->pw_passwd);
if (!pass || strcmp(pw->pw_passwd, pass))
{
# ifdef HAVE_SHADOW_H
if (spw)
{
- pass = cups_crypt(password, spw->sp_pwdp);
+ pass = crypt(password, spw->sp_pwdp);
if (pass == NULL || strcmp(spw->sp_pwdp, pass))
{
const char *groupname) /* I - Group name */
{
int i; /* Looping var */
- struct group *group; /* System group info */
+ struct group *group; /* Group info */
+ gid_t groupid; /* ID of named group */
#ifdef HAVE_MBR_UID_TO_UUID
uuid_t useruuid, /* UUID for username */
groupuuid; /* UUID for groupname */
* Group exists, check it...
*/
+ groupid = group->gr_gid;
+
#ifdef HAVE_GETGROUPLIST
if (user)
{
- int ngroups, /* Number of groups */
- groups[2048]; /* Groups that user belongs to */
+ int ngroups; /* Number of groups */
+# ifdef __APPLE__
+ int groups[2048]; /* Groups that user belongs to */
+# else
+ gid_t groups[2048]; /* Groups that user belongs to */
+# endif /* __APPLE__ */
ngroups = (int)(sizeof(groups) / sizeof(groups[0]));
+# ifdef __APPLE__
getgrouplist(username, (int)user->pw_gid, groups, &ngroups);
+# else
+ getgrouplist(username, user->pw_gid, groups, &ngroups);
+#endif /* __APPLE__ */
for (i = 0; i < ngroups; i ++)
- if ((int)group->gr_gid == groups[i])
+ if ((int)groupid == (int)groups[i])
return (1);
}
-#endif /* HAVE_GETGROUPLIST */
+#else
for (i = 0; group->gr_mem[i]; i ++)
+ {
if (!_cups_strcasecmp(username, group->gr_mem[i]))
return (1);
+ }
+#endif /* HAVE_GETGROUPLIST */
}
+ else
+ groupid = (gid_t)-1;
/*
* Group doesn't exist or user not in group list, check the group ID
* against the user's group ID...
*/
- if (user && group && group->gr_gid == user->pw_gid)
+ if (user && groupid == user->pw_gid)
return (1);
#ifdef HAVE_MBR_UID_TO_UUID
/*
- * Check group membership through MacOS X membership API...
+ * Check group membership through macOS membership API...
*/
if (user && !mbr_uid_to_uuid(user->pw_uid, useruuid))
{
- if (group)
+ if (groupid != (gid_t)-1)
{
/*
* Map group name to UUID and check membership...
*/
- if (!mbr_gid_to_uuid(group->gr_gid, groupuuid))
+ if (!mbr_gid_to_uuid(groupid, groupuuid))
if (!mbr_check_membership(useruuid, groupuuid, &is_member))
if (is_member)
return (1);
}
-#if !HAVE_LIBPAM
-/*
- * 'cups_crypt()' - Encrypt the password using the DES or MD5 algorithms,
- * as needed.
- */
-
-static char * /* O - Encrypted password */
-cups_crypt(const char *pw, /* I - Password string */
- const char *salt) /* I - Salt (key) string */
-{
- if (!strncmp(salt, "$1$", 3))
- {
- /*
- * Use MD5 passwords without the benefit of PAM; this is for
- * Slackware Linux, and the algorithm was taken from the
- * old shadow-19990827/lib/md5crypt.c source code... :(
- */
-
- int i; /* Looping var */
- unsigned long n; /* Output number */
- int pwlen; /* Length of password string */
- const char *salt_end; /* End of "salt" data for MD5 */
- char *ptr; /* Pointer into result string */
- _cups_md5_state_t state; /* Primary MD5 state info */
- _cups_md5_state_t state2; /* Secondary MD5 state info */
- unsigned char digest[16]; /* MD5 digest result */
- static char result[120]; /* Final password string */
-
-
- /*
- * Get the salt data between dollar signs, e.g. $1$saltdata$md5.
- * Get a maximum of 8 characters of salt data after $1$...
- */
-
- for (salt_end = salt + 3; *salt_end && (salt_end - salt) < 11; salt_end ++)
- if (*salt_end == '$')
- break;
-
- /*
- * Compute the MD5 sum we need...
- */
-
- pwlen = strlen(pw);
-
- _cupsMD5Init(&state);
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
- _cupsMD5Append(&state, (unsigned char *)salt, salt_end - salt);
-
- _cupsMD5Init(&state2);
- _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
- _cupsMD5Append(&state2, (unsigned char *)salt + 3, salt_end - salt - 3);
- _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
- _cupsMD5Finish(&state2, digest);
-
- for (i = pwlen; i > 0; i -= 16)
- _cupsMD5Append(&state, digest, i > 16 ? 16 : i);
-
- for (i = pwlen; i > 0; i >>= 1)
- _cupsMD5Append(&state, (unsigned char *)((i & 1) ? "" : pw), 1);
-
- _cupsMD5Finish(&state, digest);
-
- for (i = 0; i < 1000; i ++)
- {
- _cupsMD5Init(&state);
-
- if (i & 1)
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
- else
- _cupsMD5Append(&state, digest, 16);
-
- if (i % 3)
- _cupsMD5Append(&state, (unsigned char *)salt + 3, salt_end - salt - 3);
-
- if (i % 7)
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
-
- if (i & 1)
- _cupsMD5Append(&state, digest, 16);
- else
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
-
- _cupsMD5Finish(&state, digest);
- }
-
- /*
- * Copy the final sum to the result string and return...
- */
-
- memcpy(result, salt, (size_t)(salt_end - salt));
- ptr = result + (salt_end - salt);
- *ptr++ = '$';
-
- for (i = 0; i < 5; i ++, ptr += 4)
- {
- n = ((((unsigned)digest[i] << 8) | (unsigned)digest[i + 6]) << 8);
-
- if (i < 4)
- n |= (unsigned)digest[i + 12];
- else
- n |= (unsigned)digest[5];
-
- to64(ptr, n, 4);
- }
-
- to64(ptr, (unsigned)digest[11], 2);
- ptr += 2;
- *ptr = '\0';
-
- return (result);
- }
- else
- {
- /*
- * Use the standard crypt() function...
- */
-
- return (crypt(pw, salt));
- }
-}
-#endif /* !HAVE_LIBPAM */
-
-
/*
* 'free_authmask()' - Free function for auth masks.
*/
* Answer all of the messages...
*/
- DEBUG_printf(("pam_func: appdata_ptr = %p\n", appdata_ptr));
-
data = (cupsd_authdata_t *)appdata_ptr;
for (i = 0; i < num_msg; i ++)
{
- DEBUG_printf(("pam_func: Message = \"%s\"\n", msg[i]->msg));
-
switch (msg[i]->msg_style)
{
case PAM_PROMPT_ECHO_ON:
- DEBUG_printf(("pam_func: PAM_PROMPT_ECHO_ON, returning \"%s\"...\n",
- data->username));
replies[i].resp_retcode = PAM_SUCCESS;
replies[i].resp = strdup(data->username);
break;
case PAM_PROMPT_ECHO_OFF:
- DEBUG_printf(("pam_func: PAM_PROMPT_ECHO_OFF, returning \"%s\"...\n",
- data->password));
replies[i].resp_retcode = PAM_SUCCESS;
replies[i].resp = strdup(data->password);
break;
case PAM_TEXT_INFO:
- DEBUG_puts("pam_func: PAM_TEXT_INFO...");
replies[i].resp_retcode = PAM_SUCCESS;
replies[i].resp = NULL;
break;
case PAM_ERROR_MSG:
- DEBUG_puts("pam_func: PAM_ERROR_MSG...");
replies[i].resp_retcode = PAM_SUCCESS;
replies[i].resp = NULL;
break;
default:
- DEBUG_printf(("pam_func: Unknown PAM message %d...\n",
- msg[i]->msg_style));
free(replies);
return (PAM_CONV_ERR);
}