openbsd-ports/sysutils/accountsservice/patches/patch-src_daemon_c
2022-03-11 19:57:10 +00:00

344 lines
12 KiB
Plaintext

Index: src/daemon.c
--- src/daemon.c.orig
+++ src/daemon.c
@@ -36,6 +36,10 @@
#include <errno.h>
#include <sys/types.h>
+#ifdef __OpenBSD__
+#include <grp.h> /* getgrnam */
+#endif
+
#include <glib.h>
#include <glib/gi18n.h>
#include <glib-object.h>
@@ -81,7 +85,11 @@ typedef struct {
GHashTable *extension_ifaces;
} DaemonPrivate;
+#ifdef HAVE_SHADOW_H
typedef struct passwd * (* EntryGeneratorFunc) (Daemon *, GHashTable *, gpointer *, struct spwd **shadow_entry);
+#else
+typedef struct passwd * (* EntryGeneratorFunc) (Daemon *, GHashTable *, gpointer *);
+#endif
typedef struct {
Daemon *daemon;
@@ -165,17 +173,25 @@ remove_cache_files (const gchar *user_name)
}
static struct passwd *
+#ifdef HAVE_SHADOW_H
entry_generator_fgetpwent (Daemon *daemon,
GHashTable *users,
gpointer *state,
struct spwd **spent)
+#else
+entry_generator_fgetpwent (Daemon *daemon,
+ GHashTable *users,
+ gpointer *state)
+#endif
{
struct passwd *pwent;
+#ifdef HAVE_SHADOW_H
struct {
struct spwd spbuf;
char buf[1024];
} *shadow_entry_buffers;
+#endif
struct {
FILE *fp;
@@ -184,8 +200,11 @@ entry_generator_fgetpwent (Daemon *daemon,
/* First iteration */
if (*state == NULL) {
+#ifdef HAVE_SHADOW_H
GHashTable *shadow_users = NULL;
+#endif
FILE *fp;
+#ifdef HAVE_SHADOW_H
struct spwd *shadow_entry;
fp = fopen (PATH_SHADOW, "r");
@@ -219,17 +238,22 @@ entry_generator_fgetpwent (Daemon *daemon,
g_clear_pointer (&shadow_users, g_hash_table_unref);
return NULL;
}
+#endif
fp = fopen (PATH_PASSWD, "r");
if (fp == NULL) {
+#ifdef HAVE_SHADOW_H
g_clear_pointer (&shadow_users, g_hash_table_unref);
+#endif
g_warning ("Unable to open %s: %s", PATH_PASSWD, g_strerror (errno));
return NULL;
}
generator_state = g_malloc0 (sizeof (*generator_state));
generator_state->fp = fp;
+#ifdef HAVE_SHADOW_H
generator_state->users = shadow_users;
+#endif
*state = generator_state;
}
@@ -240,18 +264,22 @@ entry_generator_fgetpwent (Daemon *daemon,
if (g_hash_table_size (users) < MAX_LOCAL_USERS) {
pwent = fgetpwent (generator_state->fp);
if (pwent != NULL) {
+#ifdef HAVE_SHADOW_H
shadow_entry_buffers = g_hash_table_lookup (generator_state->users, pwent->pw_name);
if (shadow_entry_buffers != NULL) {
*spent = &shadow_entry_buffers->spbuf;
}
+#endif
return pwent;
}
}
/* Last iteration */
fclose (generator_state->fp);
+#ifdef HAVE_SHADOW_H
g_hash_table_unref (generator_state->users);
+#endif
g_free (generator_state);
*state = NULL;
@@ -259,10 +287,16 @@ entry_generator_fgetpwent (Daemon *daemon,
}
static struct passwd *
+#ifdef HAVE_SHADOW_H
entry_generator_cachedir (Daemon *daemon,
GHashTable *users,
gpointer *state,
struct spwd **shadow_entry)
+#else
+entry_generator_cachedir (Daemon *daemon,
+ GHashTable *users,
+ gpointer *state)
+#endif
{
struct passwd *pwent;
g_autoptr(GError) error = NULL;
@@ -304,7 +338,9 @@ entry_generator_cachedir (Daemon *daemon,
errno = 0;
pwent = getpwnam (name);
if (pwent != NULL) {
+#ifdef HAVE_SHADOW_H
*shadow_entry = getspnam (pwent->pw_name);
+#endif
return pwent;
} else if (errno == 0) {
@@ -340,10 +376,16 @@ entry_generator_cachedir (Daemon *daemon,
}
static struct passwd *
+#ifdef HAVE_SHADOW_H
entry_generator_requested_users (Daemon *daemon,
GHashTable *users,
gpointer *state,
struct spwd **shadow_entry)
+#else
+entry_generator_requested_users (Daemon *daemon,
+ GHashTable *users,
+ gpointer *state)
+#endif
{
DaemonPrivate *priv = daemon_get_instance_private (daemon);
struct passwd *pwent;
@@ -371,7 +413,9 @@ entry_generator_requested_users (Daemon *daemon,
if (pwent == NULL) {
g_debug ("user '%s' requested previously but not present on system", name);
} else {
+#ifdef HAVE_SHADOW_H
*shadow_entry = getspnam (pwent->pw_name);
+#endif
return pwent;
}
@@ -394,19 +438,29 @@ load_entries (Daemon *daemon,
DaemonPrivate *priv = daemon_get_instance_private (daemon);
gpointer generator_state = NULL;
struct passwd *pwent;
+#ifdef HAVE_SHADOW_H
struct spwd *spent = NULL;
+#endif
User *user = NULL;
g_assert (entry_generator != NULL);
for (;;) {
+#ifdef HAVE_SHADOW_H
spent = NULL;
pwent = entry_generator (daemon, users, &generator_state, &spent);
+#else
+ pwent = entry_generator (daemon, users, &generator_state);
+#endif
if (pwent == NULL)
break;
/* Skip system users... */
+#ifdef HAVE_SHADOW_H
if (!explicitly_requested && !user_classify_is_human (pwent->pw_uid, pwent->pw_name, pwent->pw_shell, spent? spent->sp_pwdp : NULL)) {
+#else
+ if (!explicitly_requested && !user_classify_is_human (pwent->pw_uid, pwent->pw_name, pwent->pw_shell, NULL)) {
+#endif
g_debug ("skipping user: %s", pwent->pw_name);
continue;
}
@@ -428,7 +482,11 @@ load_entries (Daemon *daemon,
/* freeze & update users not already in the new list */
g_object_freeze_notify (G_OBJECT (user));
+#ifdef HAVE_SHADOW_H
user_update_from_pwent (user, pwent, spent);
+#else
+ user_update_from_pwent (user, pwent);
+#endif
g_hash_table_insert (users, g_strdup (user_get_user_name (user)), user);
g_debug ("loaded user: %s", user_get_user_name (user));
@@ -843,15 +901,24 @@ throw_error (GDBusMethodInvocation *context,
}
static User *
+#ifdef HAVE_SHADOW_H
add_new_user_for_pwent (Daemon *daemon,
struct passwd *pwent,
struct spwd *spent)
+#else
+add_new_user_for_pwent (Daemon *daemon,
+ struct passwd *pwent)
+#endif
{
DaemonPrivate *priv = daemon_get_instance_private (daemon);
User *user;
user = user_new (daemon, pwent->pw_uid);
+#ifdef HAVE_SHADOW_H
user_update_from_pwent (user, pwent, spent);
+#else
+ user_update_from_pwent (user, pwent);
+#endif
user_register (user);
g_hash_table_insert (priv->users,
@@ -880,9 +947,13 @@ daemon_local_find_user_by_id (Daemon *daemon,
user = g_hash_table_lookup (priv->users, pwent->pw_name);
if (user == NULL) {
+#ifdef HAVE_SHADOW_H
struct spwd *spent;
spent = getspnam (pwent->pw_name);
user = add_new_user_for_pwent (daemon, pwent, spent);
+#else
+ user = add_new_user_for_pwent (daemon, pwent);
+#endif
priv->explicitly_requested_users = g_list_append (priv->explicitly_requested_users,
g_strdup (pwent->pw_name));
@@ -908,9 +979,13 @@ daemon_local_find_user_by_name (Daemon *daemon,
user = g_hash_table_lookup (priv->users, pwent->pw_name);
if (user == NULL) {
+#ifdef HAVE_SHADOW_H
struct spwd *spent;
spent = getspnam (pwent->pw_name);
user = add_new_user_for_pwent (daemon, pwent, spent);
+#else
+ user = add_new_user_for_pwent (daemon, pwent);
+#endif
priv->explicitly_requested_users = g_list_append (priv->explicitly_requested_users,
g_strdup (pwent->pw_name));
@@ -1096,7 +1171,11 @@ daemon_create_user_authorized_cb (Daemon
CreateUserData *cd = data;
User *user;
g_autoptr(GError) error = NULL;
+#ifndef __OpenBSD__
const gchar *argv[9];
+#else
+ const gchar *argv[11];
+#endif
g_autofree gchar *admin_groups = NULL;
if (getpwnam (cd->user_name) != NULL) {
@@ -1119,9 +1198,17 @@ daemon_create_user_authorized_cb (Daemon
argv[4] = "-G";
argv[5] = admin_groups;
+#ifdef __OpenBSD__
+ argv[6] = "-L";
+ argv[7] = "staff";
+ argv[8] = "--";
+ argv[9] = cd->user_name;
+ argv[10] = NULL;
+#else
argv[6] = "--";
argv[7] = cd->user_name;
argv[8] = NULL;
+#endif
}
else if (cd->account_type == ACCOUNT_TYPE_STANDARD) {
argv[4] = "--";
@@ -1302,6 +1389,34 @@ daemon_delete_user_authorized_cb (Daemon
return;
}
+/*
+ * Under OpenBSD there is no /etc/login.defs (for USERGROUPS_ENAB), so
+ * we need to explicitely remove the user's group if it contains no more
+ * members and matches the username.
+ */
+#ifdef __OpenBSD__
+ struct group *grp;
+ GError *grperror;
+ const gchar *grpargv[3];
+
+ grp = getgrnam (pwent->pw_name);
+
+ if ((grp != NULL) && (*grp->gr_name == *pwent->pw_name) && (*grp->gr_mem == NULL)) {
+ sys_log (context, "delete group '%d'", pwent->pw_gid);
+
+ grpargv[0] = "/usr/sbin/groupdel";
+ grpargv[1] = pwent->pw_name;
+ grpargv[2] = NULL;
+
+ grperror = NULL;
+ if (!spawn_with_login_uid (context, grpargv, &grperror)) {
+ throw_error (context, ERROR_FAILED, "running '%s' failed: %s", grpargv[0], grperror->message);
+ g_error_free (grperror);
+ return;
+ }
+ }
+#endif
+
sys_log (context, "delete user '%s' (%d)", pwent->pw_name, ud->uid);
user = daemon_local_find_user_by_id (daemon, ud->uid);
@@ -1320,11 +1435,18 @@ daemon_delete_user_authorized_cb (Daemon
argv[0] = "/usr/sbin/userdel";
if (ud->remove_files) {
+#ifdef __OpenBSD__
+ argv[1] = "-r";
+ argv[2] = "--";
+ argv[3] = pwent->pw_name;
+ argv[4] = NULL;
+#else
argv[1] = "-f";
argv[2] = "-r";
argv[3] = "--";
argv[4] = pwent->pw_name;
argv[5] = NULL;
+#endif
}
else {
argv[1] = "-f";