65
65
static void control_register_all (DBusConnection *conn);
67
67
static void control_bus_flush (void);
68
static int control_get_origin_uid (NihDBusMessage *message, uid_t *uid)
69
__attribute__ ((warn_unused_result));
117
121
if (! control_conns)
118
122
control_conns = NIH_MUST (nih_list_new (NULL));
124
if (! control_server_address) {
126
NIH_MUST (nih_strcat_sprintf (&control_server_address, NULL,
127
"%s-session/%d/%d", DBUS_ADDRESS_UPSTART, getuid (), getpid ()));
129
control_server_address = nih_strdup (NULL, DBUS_ADDRESS_UPSTART);
368
380
* Called to request that Upstart reloads its configuration from disk,
369
381
* useful when inotify is not available or the user is generally paranoid.
383
* Notes: chroot sessions are permitted to make this call.
371
385
* Returns: zero on success, negative value on raised error.
374
388
control_reload_configuration (void *data,
375
389
NihDBusMessage *message)
391
uid_t uid, origin_uid;
377
393
nih_assert (message != NULL);
397
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
398
nih_dbus_error_raise_printf (
399
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
400
_("You do not have permission to reload configuration"));
379
404
nih_info (_("Reloading configuration"));
381
406
/* This can only be called after deserialisation */
594
uid_t uid, origin_uid;
570
596
nih_assert (message != NULL);
571
597
nih_assert (name != NULL);
572
598
nih_assert (env != NULL);
602
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
603
nih_dbus_error_raise_printf (
604
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
605
_("You do not have permission to emit an event"));
574
609
/* Verify that the name is valid */
575
610
if (! strlen (name)) {
576
611
nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
783
818
* Called to flush the job logs for all jobs that ended before the log
784
819
* disk became writeable.
821
* Notes: Session Inits are permitted to make this call. In the common
822
* case of starting a Session Init as a child of a Display Manager this
823
* is somewhat meaningless, but it does mean that if a Session Init were
824
* started from a system job, behaviour would be as expected.
786
826
* Returns: zero on success, negative value on raised error.
793
833
Session *session;
834
uid_t uid, origin_uid;
795
836
nih_assert (message != NULL);
797
840
/* Get the relevant session */
798
841
session = session_from_dbus (NULL, message);
800
if (session && session->user) {
843
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
801
844
nih_dbus_error_raise_printf (
802
845
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
803
846
_("You do not have permission to notify disk is writeable"));
993
1036
* happen to own this process (which they may do in the test
994
1037
* scenario and when running Upstart as a non-privileged user).
996
if (session && session->user != uid) {
1039
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
997
1040
nih_dbus_error_raise_printf (
998
1041
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
999
1042
_("You do not have permission to request state"));
1055
1098
* own this process (which they may do in the test scenario and
1056
1099
* when running Upstart as a non-privileged user).
1058
if (session && session->user != uid) {
1101
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
1059
1102
nih_dbus_error_raise_printf (
1060
1103
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1061
1104
_("You do not have permission to request restart"));
1114
1157
* @data: not used,
1115
1158
* @message: D-Bus connection and message received,
1159
* @job_details: name and instance of job to apply operation to,
1116
1160
* @var: name[/value] pair of environment variable to set,
1117
1161
* @replace: TRUE if @name should be overwritten if already set, else
1120
1164
* Implements the SetEnv method of the com.ubuntu.Upstart
1123
* Called to request Upstart store a particular name/value pair that
1124
* will be exported to all jobs' environments.
1167
* Called to request Upstart store a particular name/value pair.
1169
* If @job_details is empty, change will be applied to all job
1170
* environments, else only apply changes to specific job environment
1171
* encoded within @job_details.
1126
1173
* Returns: zero on success, negative value on raised error.
1129
1176
control_set_env (void *data,
1130
1177
NihDBusMessage *message,
1178
char * const *job_details,
1131
1179
const char *var,
1182
uid_t uid, origin_uid;
1185
char *job_name = NULL;
1186
char *instance = NULL;
1187
nih_local char *envvar = NULL;
1137
nih_assert (message != NULL);
1189
nih_assert (message);
1190
nih_assert (job_details);
1138
1191
nih_assert (var);
1193
if (job_details[0]) {
1194
job_name = job_details[0];
1196
/* this can be a null value */
1197
instance = job_details[1];
1198
} else if (getpid () == 1) {
1199
nih_dbus_error_raise_printf (
1200
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1201
_("Not permissable to modify PID 1 job environment"));
1205
/* Verify that job name is valid */
1206
if (job_name && ! strlen (job_name)) {
1207
nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
1208
_("Job may not be empty string"));
1140
1212
uid = getuid ();
1142
1214
/* Get the relevant session */
1154
1226
* own this process (which they may do in the test scenario and
1155
1227
* when running Upstart as a non-privileged user).
1157
if (session && session->user != uid) {
1229
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
1158
1230
nih_dbus_error_raise_printf (
1159
1231
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1160
_("You do not have permission to modify the init environment"));
1232
_("You do not have permission to modify job environment"));
1164
if (job_class_environment_set (var, replace) < 0)
1236
/* If variable does not contain a delimiter, add one to ensure
1237
* it gets entered into the job environment table. Without the
1238
* delimiter, the variable will be silently ignored unless it's
1239
* already set in inits environment. But in that case there is
1240
* no point in setting such a variable to its already existing
1243
if (! strchr (var, '='))
1244
envvar = NIH_MUST (nih_sprintf (NULL, "%s=", var));
1246
envvar = NIH_MUST (nih_strdup (NULL, var));
1249
/* Modify job-specific environment */
1251
nih_assert (job->env);
1253
NIH_MUST (environ_add (&job->env, job, NULL, replace, envvar));
1257
if (job_class_environment_set (envvar, replace) < 0)
1165
1258
nih_return_no_memory_error (-1);
1173
1266
* @data: not used,
1174
1267
* @message: D-Bus connection and message received,
1268
* @job_details: name and instance of job to apply operation to,
1175
1269
* @name: variable to clear from the job environment array.
1177
1271
* Implements the UnsetEnv method of the com.ubuntu.Upstart
1183
1277
* Returns: zero on success, negative value on raised error.
1186
control_unset_env (void *data,
1187
NihDBusMessage *message,
1280
control_unset_env (void *data,
1281
NihDBusMessage *message,
1282
char * const *job_details,
1285
uid_t uid, origin_uid;
1288
char *job_name = NULL;
1289
char *instance = NULL;
1193
nih_assert (message != NULL);
1291
nih_assert (message);
1292
nih_assert (job_details);
1194
1293
nih_assert (name);
1295
if (job_details[0]) {
1296
job_name = job_details[0];
1298
/* this can be a null value */
1299
instance = job_details[1];
1300
} else if (getpid () == 1) {
1301
nih_dbus_error_raise_printf (
1302
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1303
_("Not permissable to modify PID 1 job environment"));
1307
/* Verify that job name is valid */
1308
if (job_name && ! strlen (job_name)) {
1309
nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
1310
_("Job may not be empty string"));
1196
1314
uid = getuid ();
1198
1316
/* Get the relevant session */
1210
1328
* own this process (which they may do in the test scenario and
1211
1329
* when running Upstart as a non-privileged user).
1213
if (session && session->user != uid) {
1331
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
1214
1332
nih_dbus_error_raise_printf (
1215
1333
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1216
_("You do not have permission to modify the init environment"));
1334
_("You do not have permission to modify job environment"));
1339
/* Modify job-specific environment */
1341
nih_assert (job->env);
1343
if (! environ_remove (&job->env, job, NULL, name))
1220
1349
if (job_class_environment_unset (name) < 0)
1235
1364
* @data: not used,
1236
1365
* @message: D-Bus connection and message received,
1366
* @job_details: name and instance of job to apply operation to,
1237
1367
* @name: name of environment variable to retrieve,
1238
1368
* @value: value of @name.
1248
1378
control_get_env (void *data,
1249
1379
NihDBusMessage *message,
1380
char * const *job_details,
1384
uid_t uid, origin_uid;
1253
1385
Session *session;
1255
1386
const char *tmp;
1388
char *job_name = NULL;
1389
char *instance = NULL;
1257
1391
nih_assert (message != NULL);
1392
nih_assert (job_details);
1394
if (job_details[0]) {
1395
job_name = job_details[0];
1397
/* this can be a null value */
1398
instance = job_details[1];
1399
} else if (getpid () == 1) {
1400
nih_dbus_error_raise_printf (
1401
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1402
_("Not permissable to modify PID 1 job environment"));
1406
/* Verify that job name is valid */
1407
if (job_name && ! strlen (job_name)) {
1408
nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
1409
_("Job may not be empty string"));
1261
1413
uid = getuid ();
1275
1427
* own this process (which they may do in the test scenario and
1276
1428
* when running Upstart as a non-privileged user).
1278
if (session && session->user != uid) {
1430
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
1279
1431
nih_dbus_error_raise_printf (
1280
1432
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1281
_("You do not have permission to query the init environment"));
1433
_("You do not have permission to modify job environment"));
1438
tmp = environ_get (job->env, name);
1442
*value = nih_strdup (message, tmp);
1444
nih_return_no_memory_error (-1);
1285
1449
tmp = job_class_environment_get (name);
1305
1470
* @data: not used,
1306
1471
* @message: D-Bus connection and message received,
1472
* @job_details: name and instance of job to apply operation to,
1307
1473
* @env: pointer to array of all job environment variables.
1309
1475
* Implements the ListEnv method of the com.ubuntu.Upstart
1318
1484
control_list_env (void *data,
1319
1485
NihDBusMessage *message,
1486
char * const *job_details,
1489
uid_t uid, origin_uid;
1492
char *job_name = NULL;
1493
char *instance = NULL;
1325
nih_assert (message != NULL);
1495
nih_assert (message);
1496
nih_assert (job_details);
1326
1497
nih_assert (env);
1499
if (job_details[0]) {
1500
job_name = job_details[0];
1502
/* this can be a null value */
1503
instance = job_details[1];
1506
/* Verify that job name is valid */
1507
if (job_name && ! strlen (job_name)) {
1508
nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
1509
_("Job may not be empty string"));
1328
1515
/* Get the relevant session */
1329
1516
session = session_from_dbus (NULL, message);
1333
/* Disallow users from querying Upstarts environment, unless they happen to
1518
/* Disallow users from changing Upstarts environment, unless they happen to
1334
1519
* own this process (which they may do in the test scenario and
1335
1520
* when running Upstart as a non-privileged user).
1337
if (session && session->user != uid) {
1522
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
1338
1523
nih_dbus_error_raise_printf (
1339
1524
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1340
_("You do not have permission to query the init environment"));
1525
_("You do not have permission to query job environment"));
1530
*env = nih_str_array_copy (job, NULL, job->env);
1532
nih_return_no_memory_error (-1);
1344
1537
*env = job_class_environment_get_all (message);
1346
1539
nih_return_no_memory_error (-1);
1352
1545
* control_reset_env:
1354
1547
* @data: not used,
1355
* @message: D-Bus connection and message received.
1548
* @message: D-Bus connection and message received,
1549
* @job_details: name and instance of job to apply operation to.
1357
1551
* Implements the ResetEnv method of the com.ubuntu.Upstart
1366
1560
control_reset_env (void *data,
1367
NihDBusMessage *message)
1561
NihDBusMessage *message,
1562
char * const *job_details)
1372
nih_assert (message != NULL);
1564
uid_t uid, origin_uid;
1567
char *job_name = NULL;
1568
char *instance = NULL;
1570
nih_assert (message);
1571
nih_assert (job_details);
1573
if (job_details[0]) {
1574
job_name = job_details[0];
1576
/* this can be a null value */
1577
instance = job_details[1];
1578
} else if (getpid () == 1) {
1579
nih_dbus_error_raise_printf (
1580
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1581
_("Not permissable to modify PID 1 job environment"));
1587
/* Verify that job name is valid */
1588
if (job_name && ! strlen (job_name)) {
1589
nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
1590
_("Job may not be empty string"));
1374
1594
/* Get the relevant session */
1375
1595
session = session_from_dbus (NULL, message);
1379
1597
/* Chroot sessions must not be able to influence
1380
1598
* the outside system.
1388
1606
* own this process (which they may do in the test scenario and
1389
1607
* when running Upstart as a non-privileged user).
1391
if (session && session->user != uid) {
1609
if (control_get_origin_uid (message, &origin_uid) && origin_uid != uid) {
1392
1610
nih_dbus_error_raise_printf (
1393
1611
DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
1394
_("You do not have permission to reset the init environment"));
1612
_("You do not have permission to modify job environment"));
1619
nih_free (job->env);
1623
job->env = job_class_environment (job, job->class, &len);
1625
nih_return_system_error (-1);
1398
1630
job_class_environment_reset ();
1636
* control_get_origin_uid:
1637
* @message: D-Bus connection and message received,
1638
* @uid: returned uid value.
1640
* Returns TRUE: if @uid now contains uid corresponding to @message,
1644
control_get_origin_uid (NihDBusMessage *message, uid_t *uid)
1646
DBusError dbus_error;
1647
unsigned long unix_user = 0;
1650
nih_assert (message);
1653
dbus_error_init (&dbus_error);
1655
sender = dbus_message_get_sender (message->message);
1657
unix_user = dbus_bus_get_unix_user (message->connection, sender,
1659
if (unix_user == (unsigned long)-1) {
1660
dbus_error_free (&dbus_error);
1664
if (! dbus_connection_get_unix_user (message->connection,
1670
*uid = (uid_t)unix_user;