~upstart-devel/upstart/trunk

« back to all changes in this revision

Viewing changes to init/control.c

* Merge of lp:~jamesodhunt/upstart/remove-basic-user-sessions.
  (Note: won't compile due to dependency of commit about to be applied).

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
static void  control_register_all   (DBusConnection *conn);
66
66
 
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));
68
70
 
69
71
/**
70
72
 * use_session_bus:
80
82
 *
81
83
 * Address on which the control server may be reached.
82
84
 **/
83
 
const char *control_server_address = DBUS_ADDRESS_UPSTART;
 
85
char *control_server_address = NULL;
84
86
 
85
87
/**
86
88
 * control_server:
105
107
 **/
106
108
NihList *control_conns = NULL;
107
109
 
 
110
/* External definitions */
 
111
extern int user_mode;
108
112
 
109
113
/**
110
114
 * control_init:
116
120
{
117
121
        if (! control_conns)
118
122
                control_conns = NIH_MUST (nih_list_new (NULL));
 
123
 
 
124
        if (! control_server_address) {
 
125
                if (user_mode)
 
126
                        NIH_MUST (nih_strcat_sprintf (&control_server_address, NULL,
 
127
                                            "%s-session/%d/%d", DBUS_ADDRESS_UPSTART, getuid (), getpid ()));
 
128
                else
 
129
                        control_server_address = nih_strdup (NULL, DBUS_ADDRESS_UPSTART);
 
130
        }
119
131
}
120
132
 
121
133
 
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.
370
382
 *
 
383
 * Notes: chroot sessions are permitted to make this call.
 
384
 *
371
385
 * Returns: zero on success, negative value on raised error.
372
386
 **/
373
387
int
374
388
control_reload_configuration (void           *data,
375
389
                              NihDBusMessage *message)
376
390
{
 
391
        uid_t     uid, origin_uid;
 
392
 
377
393
        nih_assert (message != NULL);
378
394
 
 
395
        uid = getuid ();
 
396
 
 
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"));
 
401
                return -1;
 
402
        }
 
403
 
379
404
        nih_info (_("Reloading configuration"));
380
405
 
381
406
        /* This can only be called after deserialisation */
564
589
                              int              wait,
565
590
                              int              file)
566
591
{
567
 
        Event   *event;
568
 
        Blocked *blocked;
 
592
        Event    *event;
 
593
        Blocked  *blocked;
 
594
        uid_t     uid, origin_uid;
569
595
 
570
596
        nih_assert (message != NULL);
571
597
        nih_assert (name != NULL);
572
598
        nih_assert (env != NULL);
573
599
 
 
600
        uid = getuid ();
 
601
 
 
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"));
 
606
                return -1;
 
607
        }
 
608
 
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.
785
820
 *
 
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.
 
825
 *
786
826
 * Returns: zero on success, negative value on raised error.
787
827
 **/
788
828
int
791
831
{
792
832
        int       ret;
793
833
        Session  *session;
 
834
        uid_t     uid, origin_uid;
794
835
 
795
836
        nih_assert (message != NULL);
796
837
 
 
838
        uid = getuid ();
 
839
 
797
840
        /* Get the relevant session */
798
841
        session = session_from_dbus (NULL, message);
799
842
 
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"));
968
1011
                   char           **state)
969
1012
{
970
1013
        Session  *session;
971
 
        uid_t     uid;
 
1014
        uid_t     uid, origin_uid;
972
1015
        size_t    len;
973
1016
 
974
1017
        nih_assert (message);
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).
995
1038
         */
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"));
1031
1074
                 NihDBusMessage *message)
1032
1075
{
1033
1076
        Session  *session;
1034
 
        uid_t     uid;
 
1077
        uid_t     origin_uid, uid;
1035
1078
 
1036
1079
        nih_assert (message != NULL);
1037
1080
 
1055
1098
         * own this process (which they may do in the test scenario and
1056
1099
         * when running Upstart as a non-privileged user).
1057
1100
         */
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"));
1113
1156
 *
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
1118
1162
 *  FALSE.
1120
1164
 * Implements the SetEnv method of the com.ubuntu.Upstart
1121
1165
 * interface.
1122
1166
 *
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.
 
1168
 *
 
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.
1125
1172
 *
1126
1173
 * Returns: zero on success, negative value on raised error.
1127
1174
 **/
1128
1175
int
1129
1176
control_set_env (void            *data,
1130
1177
                 NihDBusMessage  *message,
 
1178
                 char * const    *job_details,
1131
1179
                 const char      *var,
1132
1180
                 int              replace)
1133
1181
{
1134
 
        Session   *session;
1135
 
        uid_t      uid;
 
1182
        uid_t            uid, origin_uid;
 
1183
        Session         *session;
 
1184
        Job             *job = NULL;
 
1185
        char            *job_name = NULL;
 
1186
        char            *instance = NULL;
 
1187
        nih_local char  *envvar = NULL;
1136
1188
 
1137
 
        nih_assert (message != NULL);
 
1189
        nih_assert (message);
 
1190
        nih_assert (job_details);
1138
1191
        nih_assert (var);
1139
1192
 
 
1193
        if (job_details[0]) {
 
1194
                job_name = job_details[0];
 
1195
 
 
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"));
 
1202
                return -1;
 
1203
        }
 
1204
 
 
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"));
 
1209
                return -1;
 
1210
        }
 
1211
 
1140
1212
        uid = getuid ();
1141
1213
 
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).
1156
1228
         */
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"));
1161
1233
                return -1;
1162
1234
        }
1163
1235
 
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
 
1241
         * value.
 
1242
         */
 
1243
        if (! strchr (var, '='))
 
1244
                envvar = NIH_MUST (nih_sprintf (NULL, "%s=", var));
 
1245
        else
 
1246
                envvar = NIH_MUST (nih_strdup (NULL, var));
 
1247
 
 
1248
        if (job) {
 
1249
                /* Modify job-specific environment */
 
1250
 
 
1251
                nih_assert (job->env);
 
1252
 
 
1253
                NIH_MUST (environ_add (&job->env, job, NULL, replace, envvar));
 
1254
                return 0;
 
1255
        }
 
1256
 
 
1257
        if (job_class_environment_set (envvar, replace) < 0)
1165
1258
                nih_return_no_memory_error (-1);
1166
1259
 
1167
1260
        return 0;
1172
1265
 *
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.
1176
1270
 *
1177
1271
 * Implements the UnsetEnv method of the com.ubuntu.Upstart
1183
1277
 * Returns: zero on success, negative value on raised error.
1184
1278
 **/
1185
1279
int
1186
 
control_unset_env (void           *data,
1187
 
                   NihDBusMessage *message,
1188
 
                   const char     *name)
 
1280
control_unset_env (void            *data,
 
1281
                   NihDBusMessage  *message,
 
1282
                   char * const    *job_details,
 
1283
                   const char      *name)
1189
1284
{
1190
 
        Session     *session;
1191
 
        uid_t        uid;
 
1285
        uid_t            uid, origin_uid;
 
1286
        Session         *session;
 
1287
        Job             *job = NULL;
 
1288
        char            *job_name = NULL;
 
1289
        char            *instance = NULL;
1192
1290
 
1193
 
        nih_assert (message != NULL);
 
1291
        nih_assert (message);
 
1292
        nih_assert (job_details);
1194
1293
        nih_assert (name);
1195
1294
 
 
1295
        if (job_details[0]) {
 
1296
                job_name = job_details[0];
 
1297
 
 
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"));
 
1304
                return -1;
 
1305
        }
 
1306
 
 
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"));
 
1311
                return -1;
 
1312
        }
 
1313
 
1196
1314
        uid = getuid ();
1197
1315
 
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).
1212
1330
         */
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"));
1217
1335
                return -1;
1218
1336
        }
1219
1337
 
 
1338
        if (job) {
 
1339
                /* Modify job-specific environment */
 
1340
 
 
1341
                nih_assert (job->env);
 
1342
 
 
1343
                if (! environ_remove (&job->env, job, NULL, name))
 
1344
                        return -1;
 
1345
 
 
1346
                return 0;
 
1347
        }
 
1348
 
1220
1349
        if (job_class_environment_unset (name) < 0)
1221
1350
                goto error;
1222
1351
 
1234
1363
 *
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.
1239
1369
 *
1247
1377
int
1248
1378
control_get_env (void             *data,
1249
1379
                 NihDBusMessage   *message,
1250
 
                 char             *name,
 
1380
                 char * const     *job_details,
 
1381
                 const char       *name,
1251
1382
                 char            **value)
1252
1383
{
 
1384
        uid_t        uid, origin_uid;
1253
1385
        Session     *session;
1254
 
        uid_t        uid;
1255
1386
        const char  *tmp;
 
1387
        Job         *job = NULL;
 
1388
        char        *job_name = NULL;
 
1389
        char        *instance = NULL;
1256
1390
 
1257
1391
        nih_assert (message != NULL);
1258
 
        nih_assert (name);
1259
 
        nih_assert (value);
 
1392
        nih_assert (job_details);
 
1393
 
 
1394
        if (job_details[0]) {
 
1395
                job_name = job_details[0];
 
1396
 
 
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"));
 
1403
                return -1;
 
1404
        }
 
1405
 
 
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"));
 
1410
                return -1;
 
1411
        }
1260
1412
 
1261
1413
        uid = getuid ();
1262
1414
 
1275
1427
         * own this process (which they may do in the test scenario and
1276
1428
         * when running Upstart as a non-privileged user).
1277
1429
         */
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"));
1282
1434
                return -1;
1283
1435
        }
1284
1436
 
 
1437
        if (job) {
 
1438
                tmp = environ_get (job->env, name);
 
1439
                if (! tmp)
 
1440
                        goto error;
 
1441
 
 
1442
                *value = nih_strdup (message, tmp);
 
1443
                if (! *value)
 
1444
                        nih_return_no_memory_error (-1);
 
1445
 
 
1446
                return 0;
 
1447
        }
 
1448
 
1285
1449
        tmp = job_class_environment_get (name);
 
1450
 
1286
1451
        if (! tmp)
1287
1452
                goto error;
1288
1453
 
1304
1469
 *
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.
1308
1474
 *
1309
1475
 * Implements the ListEnv method of the com.ubuntu.Upstart
1317
1483
int
1318
1484
control_list_env (void             *data,
1319
1485
                 NihDBusMessage    *message,
 
1486
                 char * const      *job_details,
1320
1487
                 char            ***env)
1321
1488
{
1322
 
        Session     *session;
1323
 
        uid_t        uid;
 
1489
        uid_t      uid, origin_uid;
 
1490
        Session   *session;
 
1491
        Job       *job = NULL;
 
1492
        char      *job_name = NULL;
 
1493
        char      *instance = NULL;
1324
1494
 
1325
 
        nih_assert (message != NULL);
 
1495
        nih_assert (message);
 
1496
        nih_assert (job_details);
1326
1497
        nih_assert (env);
1327
1498
 
 
1499
        if (job_details[0]) {
 
1500
                job_name = job_details[0];
 
1501
 
 
1502
                /* this can be a null value */
 
1503
                instance = job_details[1];
 
1504
        }
 
1505
 
 
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"));
 
1510
                return -1;
 
1511
        }
 
1512
 
 
1513
        uid = getuid ();
 
1514
 
1328
1515
        /* Get the relevant session */
1329
1516
        session = session_from_dbus (NULL, message);
1330
1517
 
1331
 
        uid = getuid ();
1332
 
 
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).
1336
1521
         */
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"));
1341
1526
                return -1;
1342
1527
        }
1343
1528
 
 
1529
        if (job) {
 
1530
                *env = nih_str_array_copy (job, NULL, job->env);
 
1531
                if (! *env)
 
1532
                        nih_return_no_memory_error (-1);
 
1533
 
 
1534
                return 0;
 
1535
        }
 
1536
 
1344
1537
        *env = job_class_environment_get_all (message);
1345
1538
        if (! *env)
1346
1539
                nih_return_no_memory_error (-1);
1352
1545
 * control_reset_env:
1353
1546
 *
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.
1356
1550
 *
1357
1551
 * Implements the ResetEnv method of the com.ubuntu.Upstart
1358
1552
 * interface.
1364
1558
 **/
1365
1559
int
1366
1560
control_reset_env (void           *data,
1367
 
                 NihDBusMessage   *message)
 
1561
                 NihDBusMessage   *message,
 
1562
                 char * const    *job_details)
1368
1563
{
1369
 
        Session     *session;
1370
 
        uid_t        uid;
1371
 
 
1372
 
        nih_assert (message != NULL);
 
1564
        uid_t       uid, origin_uid;
 
1565
        Session    *session;
 
1566
        Job        *job = NULL;
 
1567
        char       *job_name = NULL;
 
1568
        char       *instance = NULL;
 
1569
 
 
1570
        nih_assert (message);
 
1571
        nih_assert (job_details);
 
1572
 
 
1573
        if (job_details[0]) {
 
1574
                job_name = job_details[0];
 
1575
 
 
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"));
 
1582
                return -1;
 
1583
        }
 
1584
 
 
1585
        uid = getuid ();
 
1586
 
 
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"));
 
1591
                return -1;
 
1592
        }
1373
1593
 
1374
1594
        /* Get the relevant session */
1375
1595
        session = session_from_dbus (NULL, message);
1376
1596
 
1377
 
        uid = getuid ();
1378
 
 
1379
1597
        /* Chroot sessions must not be able to influence
1380
1598
         * the outside system.
1381
1599
         */
1388
1606
         * own this process (which they may do in the test scenario and
1389
1607
         * when running Upstart as a non-privileged user).
1390
1608
         */
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"));
1395
1613
                return -1;
1396
1614
        }
1397
1615
 
 
1616
        if (job) {
 
1617
                size_t len;
 
1618
                if (job->env) {
 
1619
                        nih_free (job->env);
 
1620
                        job->env = NULL;
 
1621
                }
 
1622
 
 
1623
                job->env = job_class_environment (job, job->class, &len);
 
1624
                if (! job->env)
 
1625
                        nih_return_system_error (-1);
 
1626
 
 
1627
                return 0;
 
1628
        }
 
1629
 
1398
1630
        job_class_environment_reset ();
1399
1631
 
1400
1632
        return 0;
1401
1633
}
 
1634
 
 
1635
/**
 
1636
 * control_get_origin_uid:
 
1637
 * @message: D-Bus connection and message received,
 
1638
 * @uid: returned uid value.
 
1639
 *
 
1640
 * Returns TRUE: if @uid now contains uid corresponding to @message,
 
1641
 * else FALSE.
 
1642
 **/
 
1643
static int
 
1644
control_get_origin_uid (NihDBusMessage *message, uid_t *uid)
 
1645
{
 
1646
        DBusError       dbus_error;
 
1647
        unsigned long   unix_user = 0;
 
1648
        const char     *sender;
 
1649
 
 
1650
        nih_assert (message);
 
1651
        nih_assert (uid);
 
1652
 
 
1653
        dbus_error_init (&dbus_error);
 
1654
 
 
1655
        sender = dbus_message_get_sender (message->message);
 
1656
        if (sender) {
 
1657
                unix_user = dbus_bus_get_unix_user (message->connection, sender,
 
1658
                                                    &dbus_error);
 
1659
                if (unix_user == (unsigned long)-1) {
 
1660
                        dbus_error_free (&dbus_error);
 
1661
                        return FALSE;
 
1662
                }
 
1663
        } else {
 
1664
                if (! dbus_connection_get_unix_user (message->connection,
 
1665
                                                     &unix_user)) {
 
1666
                        return FALSE;
 
1667
                }
 
1668
        }
 
1669
 
 
1670
        *uid = (uid_t)unix_user;
 
1671
 
 
1672
        return TRUE;
 
1673
}